summaryrefslogtreecommitdiff
path: root/core/fpdfapi/fpdf_parser
diff options
context:
space:
mode:
authordsinclair <dsinclair@chromium.org>2016-10-04 11:55:50 -0700
committerCommit bot <commit-bot@chromium.org>2016-10-04 11:55:51 -0700
commit488b7ad845d6de212d89cd957303b294ecfa5922 (patch)
treeadfdd2327724bd3597a1a7614bbe29a01a0c8dc0 /core/fpdfapi/fpdf_parser
parent41872fa5ac7448a50f66ad56d7bde8d1aa77db4b (diff)
downloadpdfium-488b7ad845d6de212d89cd957303b294ecfa5922.tar.xz
Move core/fpdfapi/fpdf_parser to core/fpdfapi/parser
BUG=pdfium:603 Review-Url: https://codereview.chromium.org/2392603004
Diffstat (limited to 'core/fpdfapi/fpdf_parser')
-rw-r--r--core/fpdfapi/fpdf_parser/cfdf_document.cpp102
-rw-r--r--core/fpdfapi/fpdf_parser/cfdf_document.h42
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_array.cpp200
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_array.h72
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_array_unittest.cpp180
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_boolean.cpp45
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_boolean.h35
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_crypto_handler.cpp342
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_crypto_handler.h70
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp1844
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_data_avail.h253
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_dictionary.cpp275
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_dictionary.h98
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_document.cpp1020
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_document.h145
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp524
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_hint_tables.h71
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.cpp79
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h48
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_name.cpp45
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_name.h32
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_null.cpp17
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_null.h21
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_number.cpp55
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_number.h44
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_object.cpp165
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_object.h183
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp835
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_parser.cpp1637
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_parser.h177
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_parser_embeddertest.cpp59
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_parser_unittest.cpp202
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_reference.cpp83
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_reference.h50
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_security_handler.cpp699
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_security_handler.h110
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_security_handler_embeddertest.cpp32
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_simple_parser.cpp170
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_simple_parser.h35
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_simple_parser_unittest.cpp96
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_stream.cpp119
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_stream.h61
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_stream_acc.cpp91
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_stream_acc.h46
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_string.cpp52
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_string.h39
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp997
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h101
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_syntax_parser_unittest.cpp171
-rw-r--r--core/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp575
-rw-r--r--core/fpdfapi/fpdf_parser/fpdf_parser_decode.h77
-rw-r--r--core/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp117
-rw-r--r--core/fpdfapi/fpdf_parser/fpdf_parser_decode_unittest.cpp78
-rw-r--r--core/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp221
-rw-r--r--core/fpdfapi/fpdf_parser/fpdf_parser_utility.h39
55 files changed, 0 insertions, 12976 deletions
diff --git a/core/fpdfapi/fpdf_parser/cfdf_document.cpp b/core/fpdfapi/fpdf_parser/cfdf_document.cpp
deleted file mode 100644
index 12d1e7f993..0000000000
--- a/core/fpdfapi/fpdf_parser/cfdf_document.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cfdf_document.h"
-
-#include "core/fpdfapi/edit/cpdf_creator.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h"
-#include "third_party/base/ptr_util.h"
-
-CFDF_Document::CFDF_Document()
- : CPDF_IndirectObjectHolder(),
- m_pRootDict(nullptr),
- m_pFile(nullptr),
- m_bOwnFile(FALSE),
- m_pByteStringPool(pdfium::MakeUnique<CFX_ByteStringPool>()) {}
-
-CFDF_Document::~CFDF_Document() {
- if (m_bOwnFile && m_pFile)
- m_pFile->Release();
- m_pByteStringPool.DeleteObject(); // Make weak.
-}
-
-CFDF_Document* CFDF_Document::CreateNewDoc() {
- CFDF_Document* pDoc = new CFDF_Document;
- pDoc->m_pRootDict = new CPDF_Dictionary(pDoc->GetByteStringPool());
- pDoc->AddIndirectObject(pDoc->m_pRootDict);
- pDoc->m_pRootDict->SetFor("FDF",
- new CPDF_Dictionary(pDoc->GetByteStringPool()));
- return pDoc;
-}
-
-CFDF_Document* CFDF_Document::ParseFile(IFX_FileRead* pFile, FX_BOOL bOwnFile) {
- if (!pFile)
- return nullptr;
-
- std::unique_ptr<CFDF_Document> pDoc(new CFDF_Document);
- pDoc->ParseStream(pFile, bOwnFile);
- return pDoc->m_pRootDict ? pDoc.release() : nullptr;
-}
-
-CFDF_Document* CFDF_Document::ParseMemory(const uint8_t* pData, uint32_t size) {
- return CFDF_Document::ParseFile(FX_CreateMemoryStream((uint8_t*)pData, size),
- TRUE);
-}
-
-void CFDF_Document::ParseStream(IFX_FileRead* pFile, FX_BOOL bOwnFile) {
- m_pFile = pFile;
- m_bOwnFile = bOwnFile;
- CPDF_SyntaxParser parser;
- parser.InitParser(m_pFile, 0);
- while (1) {
- bool bNumber;
- CFX_ByteString word = parser.GetNextWord(&bNumber);
- if (bNumber) {
- uint32_t objnum = FXSYS_atoui(word.c_str());
- word = parser.GetNextWord(&bNumber);
- if (!bNumber)
- break;
-
- word = parser.GetNextWord(nullptr);
- if (word != "obj")
- break;
-
- CPDF_Object* pObj = parser.GetObject(this, objnum, 0, true);
- if (!pObj)
- break;
-
- ReplaceIndirectObjectIfHigherGeneration(objnum, pObj);
- word = parser.GetNextWord(nullptr);
- if (word != "endobj")
- break;
- } else {
- if (word != "trailer")
- break;
-
- if (CPDF_Dictionary* pMainDict =
- ToDictionary(parser.GetObject(this, 0, 0, true))) {
- m_pRootDict = pMainDict->GetDictFor("Root");
- pMainDict->Release();
- }
- break;
- }
- }
-}
-
-FX_BOOL CFDF_Document::WriteBuf(CFX_ByteTextBuf& buf) const {
- if (!m_pRootDict)
- return FALSE;
-
- buf << "%FDF-1.2\r\n";
- for (const auto& pair : *this)
- buf << pair.first << " 0 obj\r\n"
- << pair.second.get() << "\r\nendobj\r\n\r\n";
-
- buf << "trailer\r\n<</Root " << m_pRootDict->GetObjNum()
- << " 0 R>>\r\n%%EOF\r\n";
- return TRUE;
-}
diff --git a/core/fpdfapi/fpdf_parser/cfdf_document.h b/core/fpdfapi/fpdf_parser/cfdf_document.h
deleted file mode 100644
index cd5b5b77bb..0000000000
--- a/core/fpdfapi/fpdf_parser/cfdf_document.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CFDF_DOCUMENT_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CFDF_DOCUMENT_H_
-
-#include "core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-#include "core/fxcrt/cfx_string_pool_template.h"
-#include "core/fxcrt/cfx_weak_ptr.h"
-#include "core/fxcrt/fx_basic.h"
-
-class CPDF_Dictionary;
-
-class CFDF_Document : public CPDF_IndirectObjectHolder {
- public:
- static CFDF_Document* CreateNewDoc();
- static CFDF_Document* ParseFile(IFX_FileRead* pFile,
- FX_BOOL bOwnFile = FALSE);
- static CFDF_Document* ParseMemory(const uint8_t* pData, uint32_t size);
- ~CFDF_Document() override;
-
- FX_BOOL WriteBuf(CFX_ByteTextBuf& buf) const;
- CPDF_Dictionary* GetRoot() const { return m_pRootDict; }
- CFX_WeakPtr<CFX_ByteStringPool> GetByteStringPool() const {
- return m_pByteStringPool;
- }
-
- protected:
- CFDF_Document();
- void ParseStream(IFX_FileRead* pFile, FX_BOOL bOwnFile);
-
- CPDF_Dictionary* m_pRootDict;
- IFX_FileRead* m_pFile;
- FX_BOOL m_bOwnFile;
- CFX_WeakPtr<CFX_ByteStringPool> m_pByteStringPool;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CFDF_DOCUMENT_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_array.cpp b/core/fpdfapi/fpdf_parser/cpdf_array.cpp
deleted file mode 100644
index 26e65bca34..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_array.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-
-#include <set>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_name.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_number.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_string.h"
-#include "third_party/base/logging.h"
-#include "third_party/base/stl_util.h"
-
-CPDF_Array::CPDF_Array() {}
-
-CPDF_Array::~CPDF_Array() {
- // Mark the object as deleted so that it will not be deleted again
- // in case of cyclic references.
- m_ObjNum = kInvalidObjNum;
- for (auto& it : m_Objects) {
- if (it)
- it->Release();
- }
-}
-
-CPDF_Object::Type CPDF_Array::GetType() const {
- return ARRAY;
-}
-
-bool CPDF_Array::IsArray() const {
- return true;
-}
-
-CPDF_Array* CPDF_Array::AsArray() {
- return this;
-}
-
-const CPDF_Array* CPDF_Array::AsArray() const {
- return this;
-}
-
-CPDF_Object* CPDF_Array::Clone() const {
- return CloneObjectNonCyclic(false);
-}
-
-CPDF_Object* CPDF_Array::CloneNonCyclic(
- bool bDirect,
- std::set<const CPDF_Object*>* pVisited) const {
- pVisited->insert(this);
- CPDF_Array* pCopy = new CPDF_Array();
- for (size_t i = 0; i < GetCount(); i++) {
- CPDF_Object* value = m_Objects[i];
- if (!pdfium::ContainsKey(*pVisited, value))
- pCopy->m_Objects.push_back(value->CloneNonCyclic(bDirect, pVisited));
- }
- return pCopy;
-}
-
-CFX_FloatRect CPDF_Array::GetRect() {
- CFX_FloatRect rect;
- if (!IsArray() || m_Objects.size() != 4)
- return rect;
-
- rect.left = GetNumberAt(0);
- rect.bottom = GetNumberAt(1);
- rect.right = GetNumberAt(2);
- rect.top = GetNumberAt(3);
- return rect;
-}
-
-CFX_Matrix CPDF_Array::GetMatrix() {
- CFX_Matrix matrix;
- if (!IsArray() || m_Objects.size() != 6)
- return matrix;
-
- matrix.Set(GetNumberAt(0), GetNumberAt(1), GetNumberAt(2), GetNumberAt(3),
- GetNumberAt(4), GetNumberAt(5));
- return matrix;
-}
-
-CPDF_Object* CPDF_Array::GetObjectAt(size_t i) const {
- if (i >= m_Objects.size())
- return nullptr;
- return m_Objects[i];
-}
-
-CPDF_Object* CPDF_Array::GetDirectObjectAt(size_t i) const {
- if (i >= m_Objects.size())
- return nullptr;
- return m_Objects[i]->GetDirect();
-}
-
-CFX_ByteString CPDF_Array::GetStringAt(size_t i) const {
- if (i >= m_Objects.size())
- return CFX_ByteString();
- return m_Objects[i]->GetString();
-}
-
-int CPDF_Array::GetIntegerAt(size_t i) const {
- if (i >= m_Objects.size())
- return 0;
- return m_Objects[i]->GetInteger();
-}
-
-FX_FLOAT CPDF_Array::GetNumberAt(size_t i) const {
- if (i >= m_Objects.size())
- return 0;
- return m_Objects[i]->GetNumber();
-}
-
-CPDF_Dictionary* CPDF_Array::GetDictAt(size_t i) const {
- CPDF_Object* p = GetDirectObjectAt(i);
- if (!p)
- return nullptr;
- if (CPDF_Dictionary* pDict = p->AsDictionary())
- return pDict;
- if (CPDF_Stream* pStream = p->AsStream())
- return pStream->GetDict();
- return nullptr;
-}
-
-CPDF_Stream* CPDF_Array::GetStreamAt(size_t i) const {
- return ToStream(GetDirectObjectAt(i));
-}
-
-CPDF_Array* CPDF_Array::GetArrayAt(size_t i) const {
- return ToArray(GetDirectObjectAt(i));
-}
-
-void CPDF_Array::RemoveAt(size_t i, size_t nCount) {
- if (i >= m_Objects.size())
- return;
-
- if (nCount <= 0 || nCount > m_Objects.size() - i)
- return;
-
- for (size_t j = 0; j < nCount; ++j) {
- if (CPDF_Object* p = m_Objects[i + j])
- p->Release();
- }
- m_Objects.erase(m_Objects.begin() + i, m_Objects.begin() + i + nCount);
-}
-
-void CPDF_Array::SetAt(size_t i, CPDF_Object* pObj) {
- ASSERT(IsArray());
- CHECK(!pObj || pObj->GetObjNum() == 0);
- if (i >= m_Objects.size()) {
- ASSERT(false);
- return;
- }
- if (CPDF_Object* pOld = m_Objects[i])
- pOld->Release();
-
- m_Objects[i] = pObj;
-}
-
-void CPDF_Array::InsertAt(size_t index, CPDF_Object* pObj) {
- ASSERT(IsArray());
- CHECK(!pObj || pObj->GetObjNum() == 0);
- if (index >= m_Objects.size()) {
- // Allocate space first.
- m_Objects.resize(index + 1, nullptr);
- m_Objects[index] = pObj;
- } else {
- // Directly insert.
- m_Objects.insert(m_Objects.begin() + index, pObj);
- }
-}
-
-void CPDF_Array::Add(CPDF_Object* pObj) {
- ASSERT(IsArray());
- CHECK(!pObj || pObj->GetObjNum() == 0);
- m_Objects.push_back(pObj);
-}
-
-void CPDF_Array::AddName(const CFX_ByteString& str) {
- Add(new CPDF_Name(str));
-}
-
-void CPDF_Array::AddString(const CFX_ByteString& str) {
- Add(new CPDF_String(str, FALSE));
-}
-
-void CPDF_Array::AddInteger(int i) {
- Add(new CPDF_Number(i));
-}
-
-void CPDF_Array::AddNumber(FX_FLOAT f) {
- Add(new CPDF_Number(f));
-}
-
-void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc,
- uint32_t objnum) {
- Add(new CPDF_Reference(pDoc, objnum));
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_array.h b/core/fpdfapi/fpdf_parser/cpdf_array.h
deleted file mode 100644
index 2d4909d50e..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_array.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_ARRAY_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_ARRAY_H_
-
-#include <set>
-#include <vector>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-#include "core/fxcrt/fx_basic.h"
-#include "core/fxcrt/fx_coordinates.h"
-
-class CPDF_Array : public CPDF_Object {
- public:
- using iterator = std::vector<CPDF_Object*>::iterator;
- using const_iterator = std::vector<CPDF_Object*>::const_iterator;
-
- CPDF_Array();
-
- // CPDF_Object.
- Type GetType() const override;
- CPDF_Object* Clone() const override;
- bool IsArray() const override;
- CPDF_Array* AsArray() override;
- const CPDF_Array* AsArray() const override;
-
- bool IsEmpty() const { return m_Objects.empty(); }
- size_t GetCount() const { return m_Objects.size(); }
- CPDF_Object* GetObjectAt(size_t index) const;
- CPDF_Object* GetDirectObjectAt(size_t index) const;
- CFX_ByteString GetStringAt(size_t index) const;
- int GetIntegerAt(size_t index) const;
- FX_FLOAT GetNumberAt(size_t index) const;
- CPDF_Dictionary* GetDictAt(size_t index) const;
- CPDF_Stream* GetStreamAt(size_t index) const;
- CPDF_Array* GetArrayAt(size_t index) const;
- FX_FLOAT GetFloatAt(size_t index) const { return GetNumberAt(index); }
- CFX_Matrix GetMatrix();
- CFX_FloatRect GetRect();
-
- void SetAt(size_t index, CPDF_Object* pObj);
- void InsertAt(size_t index, CPDF_Object* pObj);
- void RemoveAt(size_t index, size_t nCount = 1);
-
- void Add(CPDF_Object* pObj);
- void AddNumber(FX_FLOAT f);
- void AddInteger(int i);
- void AddString(const CFX_ByteString& str);
- void AddName(const CFX_ByteString& str);
- void AddReference(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum);
-
- iterator begin() { return m_Objects.begin(); }
- iterator end() { return m_Objects.end(); }
- const_iterator begin() const { return m_Objects.begin(); }
- const_iterator end() const { return m_Objects.end(); }
-
- protected:
- ~CPDF_Array() override;
-
- CPDF_Object* CloneNonCyclic(
- bool bDirect,
- std::set<const CPDF_Object*>* pVisited) const override;
-
- std::vector<CPDF_Object*> m_Objects;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_ARRAY_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_array_unittest.cpp b/core/fpdfapi/fpdf_parser/cpdf_array_unittest.cpp
deleted file mode 100644
index 110fd59e0a..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_array_unittest.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_number.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
-
-#include <memory>
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-using ScopedArray = std::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Array>>;
-
-} // namespace
-
-TEST(cpdf_array, RemoveAt) {
- {
- int elems[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(elems); ++i)
- arr->AddInteger(elems[i]);
- arr->RemoveAt(3, 3);
- int expected[] = {1, 2, 3, 7, 8, 9, 10};
- EXPECT_EQ(FX_ArraySize(expected), arr->GetCount());
- for (size_t i = 0; i < FX_ArraySize(expected); ++i)
- EXPECT_EQ(expected[i], arr->GetIntegerAt(i));
- arr->RemoveAt(4, 2);
- int expected2[] = {1, 2, 3, 7, 10};
- EXPECT_EQ(FX_ArraySize(expected2), arr->GetCount());
- for (size_t i = 0; i < FX_ArraySize(expected2); ++i)
- EXPECT_EQ(expected2[i], arr->GetIntegerAt(i));
- }
- {
- // When the range is out of bound, RemoveAt has no effect.
- int elems[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(elems); ++i)
- arr->AddInteger(elems[i]);
- arr->RemoveAt(8, 5);
- EXPECT_EQ(FX_ArraySize(elems), arr->GetCount());
- for (size_t i = 0; i < FX_ArraySize(elems); ++i)
- EXPECT_EQ(elems[i], arr->GetIntegerAt(i));
- arr->RemoveAt(0, 12);
- EXPECT_EQ(FX_ArraySize(elems), arr->GetCount());
- arr->RemoveAt(11, 1);
- EXPECT_EQ(FX_ArraySize(elems), arr->GetCount());
- }
-}
-
-TEST(cpdf_array, InsertAt) {
- {
- int elems[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(elems); ++i)
- arr->InsertAt(i, new CPDF_Number(elems[i]));
- EXPECT_EQ(FX_ArraySize(elems), arr->GetCount());
- for (size_t i = 0; i < FX_ArraySize(elems); ++i)
- EXPECT_EQ(elems[i], arr->GetIntegerAt(i));
- arr->InsertAt(3, new CPDF_Number(33));
- arr->InsertAt(6, new CPDF_Number(55));
- arr->InsertAt(12, new CPDF_Number(12));
- int expected[] = {1, 2, 3, 33, 4, 5, 55, 6, 7, 8, 9, 10, 12};
- EXPECT_EQ(FX_ArraySize(expected), arr->GetCount());
- for (size_t i = 0; i < FX_ArraySize(expected); ++i)
- EXPECT_EQ(expected[i], arr->GetIntegerAt(i));
- }
- {
- // When the position to insert is beyond the upper bound,
- // an element is inserted at that position while other unfilled
- // positions have nullptr.
- int elems[] = {1, 2};
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(elems); ++i)
- arr->InsertAt(i, new CPDF_Number(elems[i]));
- arr->InsertAt(10, new CPDF_Number(10));
- EXPECT_EQ(11u, arr->GetCount());
- for (size_t i = 0; i < FX_ArraySize(elems); ++i)
- EXPECT_EQ(elems[i], arr->GetIntegerAt(i));
- for (size_t i = FX_ArraySize(elems); i < 10; ++i)
- EXPECT_EQ(nullptr, arr->GetObjectAt(i));
- EXPECT_EQ(10, arr->GetIntegerAt(10));
- }
-}
-
-TEST(cpdf_array, Clone) {
- {
- // Basic case.
- int elems[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(elems); ++i)
- arr->InsertAt(i, new CPDF_Number(elems[i]));
- ScopedArray arr2(arr->Clone()->AsArray());
- EXPECT_EQ(arr->GetCount(), arr2->GetCount());
- for (size_t i = 0; i < FX_ArraySize(elems); ++i) {
- // Clone() always create new objects.
- EXPECT_NE(arr->GetObjectAt(i), arr2->GetObjectAt(i));
- EXPECT_EQ(arr->GetIntegerAt(i), arr2->GetIntegerAt(i));
- }
- }
- {
- // Clone() with and without dereferencing reference objects.
- static const size_t kNumOfRows = 3;
- static const size_t kNumOfRowElems = 5;
- int elems[kNumOfRows][kNumOfRowElems] = {
- {1, 2, 3, 4, 5}, {10, 9, 8, 7, 6}, {11, 12, 13, 14, 15}};
- ScopedArray arr(new CPDF_Array);
- // Indirect references to indirect objects.
- std::unique_ptr<CPDF_IndirectObjectHolder> obj_holder(
- new CPDF_IndirectObjectHolder());
- for (size_t i = 0; i < kNumOfRows; ++i) {
- CPDF_Array* arr_elem = new CPDF_Array;
- for (size_t j = 0; j < kNumOfRowElems; ++j) {
- CPDF_Number* obj = new CPDF_Number(elems[i][j]);
- // Starts object number from 1.
- int obj_num = i * kNumOfRowElems + j + 1;
- obj_holder->ReplaceIndirectObjectIfHigherGeneration(obj_num, obj);
- arr_elem->InsertAt(j, new CPDF_Reference(obj_holder.get(), obj_num));
- }
- arr->InsertAt(i, arr_elem);
- }
- ASSERT_EQ(kNumOfRows, arr->GetCount());
- // Not dereferencing reference objects means just creating new references
- // instead of new copies of direct objects.
- ScopedArray arr1(arr->Clone()->AsArray());
- EXPECT_EQ(arr->GetCount(), arr1->GetCount());
- // Dereferencing reference objects creates new copies of direct objects.
- ScopedArray arr2(arr->CloneDirectObject()->AsArray());
- EXPECT_EQ(arr->GetCount(), arr2->GetCount());
- for (size_t i = 0; i < kNumOfRows; ++i) {
- CPDF_Array* arr_elem = arr->GetObjectAt(i)->AsArray();
- CPDF_Array* arr1_elem = arr1->GetObjectAt(i)->AsArray();
- CPDF_Array* arr2_elem = arr2->GetObjectAt(i)->AsArray();
- EXPECT_NE(arr_elem, arr1_elem);
- EXPECT_NE(arr_elem, arr2_elem);
- for (size_t j = 0; j < kNumOfRowElems; ++j) {
- auto elem_obj = arr_elem->GetObjectAt(j);
- auto elem_obj1 = arr1_elem->GetObjectAt(j);
- auto elem_obj2 = arr2_elem->GetObjectAt(j);
- // Results from not deferencing reference objects.
- EXPECT_NE(elem_obj, elem_obj1);
- EXPECT_TRUE(elem_obj1->IsReference());
- EXPECT_EQ(elem_obj->GetDirect(), elem_obj1->GetDirect());
- EXPECT_EQ(elem_obj->GetInteger(), elem_obj1->GetInteger());
- // Results from deferencing reference objects.
- EXPECT_NE(elem_obj, elem_obj2);
- EXPECT_TRUE(elem_obj2->IsNumber());
- EXPECT_NE(elem_obj->GetDirect(), elem_obj2);
- EXPECT_EQ(elem_obj->GetObjNum(), elem_obj2->GetObjNum());
- EXPECT_EQ(elem_obj->GetInteger(), elem_obj2->GetInteger());
- }
- }
- arr.reset();
- ASSERT_EQ(kNumOfRows, arr1->GetCount());
- for (size_t i = 0; i < kNumOfRows; ++i) {
- for (size_t j = 0; j < kNumOfRowElems; ++j) {
- // Results from not deferencing reference objects.
- auto elem_obj1 = arr1->GetObjectAt(i)->AsArray()->GetObjectAt(j);
- EXPECT_TRUE(elem_obj1->IsReference());
- EXPECT_EQ(elems[i][j], elem_obj1->GetInteger());
- // Results from deferencing reference objects.
- EXPECT_EQ(elems[i][j],
- arr2->GetObjectAt(i)->AsArray()->GetIntegerAt(j));
- }
- }
- }
-}
-
-TEST(cpdf_array, Iterator) {
- int elems[] = {-23, -11, 3, 455, 2345877,
- 0, 7895330, -12564334, 10000, -100000};
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(elems); ++i)
- arr->InsertAt(i, new CPDF_Number(elems[i]));
- size_t index = 0;
- for (const auto& it : *arr)
- EXPECT_EQ(elems[index++], it->AsNumber()->GetInteger());
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_boolean.cpp b/core/fpdfapi/fpdf_parser/cpdf_boolean.cpp
deleted file mode 100644
index be0b7e99a3..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_boolean.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_boolean.h"
-
-CPDF_Boolean::CPDF_Boolean() : m_bValue(false) {}
-
-CPDF_Boolean::CPDF_Boolean(bool value) : m_bValue(value) {}
-
-CPDF_Boolean::~CPDF_Boolean() {}
-
-CPDF_Object::Type CPDF_Boolean::GetType() const {
- return BOOLEAN;
-}
-
-CPDF_Object* CPDF_Boolean::Clone() const {
- return new CPDF_Boolean(m_bValue);
-}
-
-CFX_ByteString CPDF_Boolean::GetString() const {
- return m_bValue ? "true" : "false";
-}
-
-int CPDF_Boolean::GetInteger() const {
- return m_bValue;
-}
-
-void CPDF_Boolean::SetString(const CFX_ByteString& str) {
- m_bValue = (str == "true");
-}
-
-bool CPDF_Boolean::IsBoolean() const {
- return true;
-}
-
-CPDF_Boolean* CPDF_Boolean::AsBoolean() {
- return this;
-}
-
-const CPDF_Boolean* CPDF_Boolean::AsBoolean() const {
- return this;
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_boolean.h b/core/fpdfapi/fpdf_parser/cpdf_boolean.h
deleted file mode 100644
index db4a11c312..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_boolean.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_BOOLEAN_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_BOOLEAN_H_
-
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-
-class CPDF_Boolean : public CPDF_Object {
- public:
- CPDF_Boolean();
- explicit CPDF_Boolean(bool value);
-
- // CPDF_Object.
- Type GetType() const override;
- CPDF_Object* Clone() const override;
- CFX_ByteString GetString() const override;
- int GetInteger() const override;
- void SetString(const CFX_ByteString& str) override;
- bool IsBoolean() const override;
- CPDF_Boolean* AsBoolean() override;
- const CPDF_Boolean* AsBoolean() const override;
-
- protected:
- ~CPDF_Boolean() override;
-
- bool m_bValue;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_BOOLEAN_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_crypto_handler.cpp b/core/fpdfapi/fpdf_parser/cpdf_crypto_handler.cpp
deleted file mode 100644
index 36f74cbd32..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_crypto_handler.cpp
+++ /dev/null
@@ -1,342 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_crypto_handler.h"
-
-#include <time.h>
-
-#include "core/fdrm/crypto/fx_crypt.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_parser.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_security_handler.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h"
-
-void CPDF_CryptoHandler::CryptBlock(FX_BOOL bEncrypt,
- uint32_t objnum,
- uint32_t gennum,
- const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t* dest_buf,
- uint32_t& dest_size) {
- if (m_Cipher == FXCIPHER_NONE) {
- FXSYS_memcpy(dest_buf, src_buf, src_size);
- return;
- }
- uint8_t realkey[16];
- int realkeylen = 16;
- if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) {
- uint8_t key1[32];
- PopulateKey(objnum, gennum, key1);
-
- if (m_Cipher == FXCIPHER_AES) {
- FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4);
- }
- CRYPT_MD5Generate(
- key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey);
- realkeylen = m_KeyLen + 5;
- if (realkeylen > 16) {
- realkeylen = 16;
- }
- }
- if (m_Cipher == FXCIPHER_AES) {
- CRYPT_AESSetKey(m_pAESContext, 16, m_KeyLen == 32 ? m_EncryptKey : realkey,
- m_KeyLen, bEncrypt);
- if (bEncrypt) {
- uint8_t iv[16];
- for (int i = 0; i < 16; i++) {
- iv[i] = (uint8_t)rand();
- }
- CRYPT_AESSetIV(m_pAESContext, iv);
- FXSYS_memcpy(dest_buf, iv, 16);
- int nblocks = src_size / 16;
- CRYPT_AESEncrypt(m_pAESContext, dest_buf + 16, src_buf, nblocks * 16);
- uint8_t padding[16];
- FXSYS_memcpy(padding, src_buf + nblocks * 16, src_size % 16);
- FXSYS_memset(padding + src_size % 16, 16 - src_size % 16,
- 16 - src_size % 16);
- CRYPT_AESEncrypt(m_pAESContext, dest_buf + nblocks * 16 + 16, padding,
- 16);
- dest_size = 32 + nblocks * 16;
- } else {
- CRYPT_AESSetIV(m_pAESContext, src_buf);
- CRYPT_AESDecrypt(m_pAESContext, dest_buf, src_buf + 16, src_size - 16);
- dest_size = src_size - 16;
- dest_size -= dest_buf[dest_size - 1];
- }
- } else {
- ASSERT(dest_size == src_size);
- if (dest_buf != src_buf) {
- FXSYS_memcpy(dest_buf, src_buf, src_size);
- }
- CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen);
- }
-}
-
-struct AESCryptContext {
- uint8_t m_Context[2048];
- FX_BOOL m_bIV;
- uint8_t m_Block[16];
- uint32_t m_BlockOffset;
-};
-
-void* CPDF_CryptoHandler::CryptStart(uint32_t objnum,
- uint32_t gennum,
- FX_BOOL bEncrypt) {
- if (m_Cipher == FXCIPHER_NONE) {
- return this;
- }
- if (m_Cipher == FXCIPHER_AES && m_KeyLen == 32) {
- AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1);
- pContext->m_bIV = TRUE;
- pContext->m_BlockOffset = 0;
- CRYPT_AESSetKey(pContext->m_Context, 16, m_EncryptKey, 32, bEncrypt);
- if (bEncrypt) {
- for (int i = 0; i < 16; i++) {
- pContext->m_Block[i] = (uint8_t)rand();
- }
- CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
- }
- return pContext;
- }
- uint8_t key1[48];
- PopulateKey(objnum, gennum, key1);
-
- if (m_Cipher == FXCIPHER_AES) {
- FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4);
- }
- uint8_t realkey[16];
- CRYPT_MD5Generate(
- key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey);
- int realkeylen = m_KeyLen + 5;
- if (realkeylen > 16) {
- realkeylen = 16;
- }
- if (m_Cipher == FXCIPHER_AES) {
- AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1);
- pContext->m_bIV = TRUE;
- pContext->m_BlockOffset = 0;
- CRYPT_AESSetKey(pContext->m_Context, 16, realkey, 16, bEncrypt);
- if (bEncrypt) {
- for (int i = 0; i < 16; i++) {
- pContext->m_Block[i] = (uint8_t)rand();
- }
- CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
- }
- return pContext;
- }
- void* pContext = FX_Alloc(uint8_t, 1040);
- CRYPT_ArcFourSetup(pContext, realkey, realkeylen);
- return pContext;
-}
-
-FX_BOOL CPDF_CryptoHandler::CryptStream(void* context,
- const uint8_t* src_buf,
- uint32_t src_size,
- CFX_BinaryBuf& dest_buf,
- FX_BOOL bEncrypt) {
- if (!context) {
- return FALSE;
- }
- if (m_Cipher == FXCIPHER_NONE) {
- dest_buf.AppendBlock(src_buf, src_size);
- return TRUE;
- }
- if (m_Cipher == FXCIPHER_RC4) {
- int old_size = dest_buf.GetSize();
- dest_buf.AppendBlock(src_buf, src_size);
- CRYPT_ArcFourCrypt(context, dest_buf.GetBuffer() + old_size, src_size);
- return TRUE;
- }
- AESCryptContext* pContext = (AESCryptContext*)context;
- if (pContext->m_bIV && bEncrypt) {
- dest_buf.AppendBlock(pContext->m_Block, 16);
- pContext->m_bIV = FALSE;
- }
- uint32_t src_off = 0;
- uint32_t src_left = src_size;
- while (1) {
- uint32_t copy_size = 16 - pContext->m_BlockOffset;
- if (copy_size > src_left) {
- copy_size = src_left;
- }
- FXSYS_memcpy(pContext->m_Block + pContext->m_BlockOffset, src_buf + src_off,
- copy_size);
- src_off += copy_size;
- src_left -= copy_size;
- pContext->m_BlockOffset += copy_size;
- if (pContext->m_BlockOffset == 16) {
- if (!bEncrypt && pContext->m_bIV) {
- CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
- pContext->m_bIV = FALSE;
- pContext->m_BlockOffset = 0;
- } else if (src_off < src_size) {
- uint8_t block_buf[16];
- if (bEncrypt) {
- CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block,
- 16);
- } else {
- CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block,
- 16);
- }
- dest_buf.AppendBlock(block_buf, 16);
- pContext->m_BlockOffset = 0;
- }
- }
- if (!src_left) {
- break;
- }
- }
- return TRUE;
-}
-FX_BOOL CPDF_CryptoHandler::CryptFinish(void* context,
- CFX_BinaryBuf& dest_buf,
- FX_BOOL bEncrypt) {
- if (!context) {
- return FALSE;
- }
- if (m_Cipher == FXCIPHER_NONE) {
- return TRUE;
- }
- if (m_Cipher == FXCIPHER_RC4) {
- FX_Free(context);
- return TRUE;
- }
- AESCryptContext* pContext = (AESCryptContext*)context;
- if (bEncrypt) {
- uint8_t block_buf[16];
- if (pContext->m_BlockOffset == 16) {
- CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
- dest_buf.AppendBlock(block_buf, 16);
- pContext->m_BlockOffset = 0;
- }
- FXSYS_memset(pContext->m_Block + pContext->m_BlockOffset,
- (uint8_t)(16 - pContext->m_BlockOffset),
- 16 - pContext->m_BlockOffset);
- CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
- dest_buf.AppendBlock(block_buf, 16);
- } else if (pContext->m_BlockOffset == 16) {
- uint8_t block_buf[16];
- CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
- if (block_buf[15] <= 16) {
- dest_buf.AppendBlock(block_buf, 16 - block_buf[15]);
- }
- }
- FX_Free(pContext);
- return TRUE;
-}
-
-void CPDF_CryptoHandler::Decrypt(uint32_t objnum,
- uint32_t gennum,
- CFX_ByteString& str) {
- CFX_BinaryBuf dest_buf;
- void* context = DecryptStart(objnum, gennum);
- DecryptStream(context, str.raw_str(), str.GetLength(), dest_buf);
- DecryptFinish(context, dest_buf);
- str = CFX_ByteString(dest_buf.GetBuffer(), dest_buf.GetSize());
-}
-
-void* CPDF_CryptoHandler::DecryptStart(uint32_t objnum, uint32_t gennum) {
- return CryptStart(objnum, gennum, FALSE);
-}
-uint32_t CPDF_CryptoHandler::DecryptGetSize(uint32_t src_size) {
- return m_Cipher == FXCIPHER_AES ? src_size - 16 : src_size;
-}
-
-FX_BOOL CPDF_CryptoHandler::Init(CPDF_Dictionary* pEncryptDict,
- CPDF_SecurityHandler* pSecurityHandler) {
- const uint8_t* key;
- if (!pSecurityHandler->GetCryptInfo(m_Cipher, key, m_KeyLen)) {
- return FALSE;
- }
- if (m_KeyLen > 32 || m_KeyLen < 0) {
- return FALSE;
- }
- if (m_Cipher != FXCIPHER_NONE) {
- FXSYS_memcpy(m_EncryptKey, key, m_KeyLen);
- }
- if (m_Cipher == FXCIPHER_AES) {
- m_pAESContext = FX_Alloc(uint8_t, 2048);
- }
- return TRUE;
-}
-
-FX_BOOL CPDF_CryptoHandler::Init(int cipher, const uint8_t* key, int keylen) {
- if (cipher == FXCIPHER_AES) {
- switch (keylen) {
- case 16:
- case 24:
- case 32:
- break;
- default:
- return FALSE;
- }
- } else if (cipher == FXCIPHER_AES2) {
- if (keylen != 32) {
- return FALSE;
- }
- } else if (cipher == FXCIPHER_RC4) {
- if (keylen < 5 || keylen > 16) {
- return FALSE;
- }
- } else {
- if (keylen > 32) {
- keylen = 32;
- }
- }
- m_Cipher = cipher;
- m_KeyLen = keylen;
- FXSYS_memcpy(m_EncryptKey, key, keylen);
- if (m_Cipher == FXCIPHER_AES) {
- m_pAESContext = FX_Alloc(uint8_t, 2048);
- }
- return TRUE;
-}
-FX_BOOL CPDF_CryptoHandler::DecryptStream(void* context,
- const uint8_t* src_buf,
- uint32_t src_size,
- CFX_BinaryBuf& dest_buf) {
- return CryptStream(context, src_buf, src_size, dest_buf, FALSE);
-}
-FX_BOOL CPDF_CryptoHandler::DecryptFinish(void* context,
- CFX_BinaryBuf& dest_buf) {
- return CryptFinish(context, dest_buf, FALSE);
-}
-uint32_t CPDF_CryptoHandler::EncryptGetSize(uint32_t objnum,
- uint32_t version,
- const uint8_t* src_buf,
- uint32_t src_size) {
- if (m_Cipher == FXCIPHER_AES) {
- return src_size + 32;
- }
- return src_size;
-}
-FX_BOOL CPDF_CryptoHandler::EncryptContent(uint32_t objnum,
- uint32_t gennum,
- const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t* dest_buf,
- uint32_t& dest_size) {
- CryptBlock(TRUE, objnum, gennum, src_buf, src_size, dest_buf, dest_size);
- return TRUE;
-}
-CPDF_CryptoHandler::CPDF_CryptoHandler() {
- m_pAESContext = nullptr;
- m_Cipher = FXCIPHER_NONE;
- m_KeyLen = 0;
-}
-CPDF_CryptoHandler::~CPDF_CryptoHandler() {
- FX_Free(m_pAESContext);
-}
-
-void CPDF_CryptoHandler::PopulateKey(uint32_t objnum,
- uint32_t gennum,
- uint8_t* key) {
- FXSYS_memcpy(key, m_EncryptKey, m_KeyLen);
- key[m_KeyLen + 0] = (uint8_t)objnum;
- key[m_KeyLen + 1] = (uint8_t)(objnum >> 8);
- key[m_KeyLen + 2] = (uint8_t)(objnum >> 16);
- key[m_KeyLen + 3] = (uint8_t)gennum;
- key[m_KeyLen + 4] = (uint8_t)(gennum >> 8);
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_crypto_handler.h b/core/fpdfapi/fpdf_parser/cpdf_crypto_handler.h
deleted file mode 100644
index 25ff49b482..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_crypto_handler.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_CRYPTO_HANDLER_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_CRYPTO_HANDLER_H_
-
-#include "core/fxcrt/fx_basic.h"
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-
-class CPDF_Dictionary;
-class CPDF_SecurityHandler;
-
-class CPDF_CryptoHandler {
- public:
- CPDF_CryptoHandler();
- ~CPDF_CryptoHandler();
-
- FX_BOOL Init(CPDF_Dictionary* pEncryptDict,
- CPDF_SecurityHandler* pSecurityHandler);
- uint32_t DecryptGetSize(uint32_t src_size);
- void* DecryptStart(uint32_t objnum, uint32_t gennum);
- void Decrypt(uint32_t objnum, uint32_t gennum, CFX_ByteString& str);
- FX_BOOL DecryptStream(void* context,
- const uint8_t* src_buf,
- uint32_t src_size,
- CFX_BinaryBuf& dest_buf);
- FX_BOOL DecryptFinish(void* context, CFX_BinaryBuf& dest_buf);
- uint32_t EncryptGetSize(uint32_t objnum,
- uint32_t version,
- const uint8_t* src_buf,
- uint32_t src_size);
- FX_BOOL EncryptContent(uint32_t objnum,
- uint32_t version,
- const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t* dest_buf,
- uint32_t& dest_size);
-
- FX_BOOL Init(int cipher, const uint8_t* key, int keylen);
-
- protected:
- void CryptBlock(FX_BOOL bEncrypt,
- uint32_t objnum,
- uint32_t gennum,
- const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t* dest_buf,
- uint32_t& dest_size);
- void* CryptStart(uint32_t objnum, uint32_t gennum, FX_BOOL bEncrypt);
- FX_BOOL CryptStream(void* context,
- const uint8_t* src_buf,
- uint32_t src_size,
- CFX_BinaryBuf& dest_buf,
- FX_BOOL bEncrypt);
- FX_BOOL CryptFinish(void* context, CFX_BinaryBuf& dest_buf, FX_BOOL bEncrypt);
-
- uint8_t m_EncryptKey[32];
- int m_KeyLen;
- int m_Cipher;
- uint8_t* m_pAESContext;
-
- private:
- void PopulateKey(uint32_t objnum, uint32_t gennum, uint8_t* key);
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_CRYPTO_HANDLER_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp b/core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp
deleted file mode 100644
index 9afe4e5f13..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp
+++ /dev/null
@@ -1,1844 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_data_avail.h"
-
-#include <algorithm>
-#include <memory>
-#include <utility>
-
-#include "core/fpdfapi/cpdf_modulemgr.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_document.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_hint_tables.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_name.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_number.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h"
-#include "core/fxcrt/fx_ext.h"
-#include "core/fxcrt/fx_safe_types.h"
-#include "third_party/base/stl_util.h"
-
-CPDF_DataAvail::FileAvail::~FileAvail() {}
-
-CPDF_DataAvail::DownloadHints::~DownloadHints() {}
-
-// static
-int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0;
-
-CPDF_DataAvail::CPDF_DataAvail(FileAvail* pFileAvail,
- IFX_FileRead* pFileRead,
- FX_BOOL bSupportHintTable)
- : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {
- m_Pos = 0;
- m_dwFileLen = 0;
- if (m_pFileRead) {
- m_dwFileLen = (uint32_t)m_pFileRead->GetSize();
- }
- m_dwCurrentOffset = 0;
- m_dwXRefOffset = 0;
- m_bufferOffset = 0;
- m_dwFirstPageNo = 0;
- m_bufferSize = 0;
- m_PagesObjNum = 0;
- m_dwCurrentXRefSteam = 0;
- m_dwAcroFormObjNum = 0;
- m_dwInfoObjNum = 0;
- m_pDocument = 0;
- m_dwEncryptObjNum = 0;
- m_dwPrevXRefOffset = 0;
- m_dwLastXRefOffset = 0;
- m_bDocAvail = FALSE;
- m_bMainXRefLoadTried = FALSE;
- m_bDocAvail = FALSE;
- m_bLinearized = FALSE;
- m_bPagesLoad = FALSE;
- m_bPagesTreeLoad = FALSE;
- m_bMainXRefLoadedOK = FALSE;
- m_bAnnotsLoad = FALSE;
- m_bHaveAcroForm = FALSE;
- m_bAcroFormLoad = FALSE;
- m_bPageLoadedOK = FALSE;
- m_bNeedDownLoadResource = FALSE;
- m_bLinearizedFormParamLoad = FALSE;
- m_pLinearized = nullptr;
- m_pRoot = nullptr;
- m_pTrailer = nullptr;
- m_pCurrentParser = nullptr;
- m_pAcroForm = nullptr;
- m_pPageDict = nullptr;
- m_pPageResource = nullptr;
- m_docStatus = PDF_DATAAVAIL_HEADER;
- m_parser.m_bOwnFileRead = false;
- m_bTotalLoadPageTree = FALSE;
- m_bCurPageDictLoadOK = FALSE;
- m_bLinearedDataOK = FALSE;
- m_bSupportHintTable = bSupportHintTable;
-}
-CPDF_DataAvail::~CPDF_DataAvail() {
- m_pHintTables.reset();
- if (m_pLinearized)
- m_pLinearized->Release();
-
- if (m_pRoot)
- m_pRoot->Release();
-
- if (m_pTrailer)
- m_pTrailer->Release();
-
- int iSize = m_arrayAcroforms.GetSize();
- for (int i = 0; i < iSize; ++i)
- m_arrayAcroforms.GetAt(i)->Release();
-}
-
-void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc) {
- m_pDocument = pDoc;
-}
-
-uint32_t CPDF_DataAvail::GetObjectSize(uint32_t objnum, FX_FILESIZE& offset) {
- CPDF_Parser* pParser = m_pDocument->GetParser();
- if (!pParser || !pParser->IsValidObjectNumber(objnum))
- return 0;
-
- if (pParser->GetObjectType(objnum) == 2)
- objnum = pParser->GetObjectPositionOrZero(objnum);
-
- if (pParser->GetObjectType(objnum) != 1 &&
- pParser->GetObjectType(objnum) != 255) {
- return 0;
- }
-
- offset = pParser->GetObjectPositionOrZero(objnum);
- if (offset == 0)
- return 0;
-
- auto it = pParser->m_SortedOffset.find(offset);
- if (it == pParser->m_SortedOffset.end() ||
- ++it == pParser->m_SortedOffset.end()) {
- return 0;
- }
- return *it - offset;
-}
-
-FX_BOOL CPDF_DataAvail::IsObjectsAvail(
- CFX_ArrayTemplate<CPDF_Object*>& obj_array,
- FX_BOOL bParsePage,
- DownloadHints* pHints,
- CFX_ArrayTemplate<CPDF_Object*>& ret_array) {
- if (!obj_array.GetSize())
- return TRUE;
-
- uint32_t count = 0;
- CFX_ArrayTemplate<CPDF_Object*> new_obj_array;
- for (int i = 0; i < obj_array.GetSize(); i++) {
- CPDF_Object* pObj = obj_array[i];
- if (!pObj)
- continue;
-
- int32_t type = pObj->GetType();
- switch (type) {
- case CPDF_Object::ARRAY: {
- CPDF_Array* pArray = pObj->AsArray();
- for (size_t k = 0; k < pArray->GetCount(); ++k)
- new_obj_array.Add(pArray->GetObjectAt(k));
- } break;
- case CPDF_Object::STREAM:
- pObj = pObj->GetDict();
- case CPDF_Object::DICTIONARY: {
- CPDF_Dictionary* pDict = pObj->GetDict();
- if (pDict && pDict->GetStringFor("Type") == "Page" && !bParsePage)
- continue;
-
- for (const auto& it : *pDict) {
- const CFX_ByteString& key = it.first;
- CPDF_Object* value = it.second;
- if (key != "Parent")
- new_obj_array.Add(value);
- }
- } break;
- case CPDF_Object::REFERENCE: {
- CPDF_Reference* pRef = pObj->AsReference();
- uint32_t dwNum = pRef->GetRefObjNum();
-
- FX_FILESIZE offset;
- uint32_t size = GetObjectSize(dwNum, offset);
- if (size == 0 || offset < 0 || offset >= m_dwFileLen)
- break;
-
- if (!IsDataAvail(offset, size, pHints)) {
- ret_array.Add(pObj);
- count++;
- } else if (!pdfium::ContainsKey(m_ObjectSet, dwNum)) {
- m_ObjectSet.insert(dwNum);
- CPDF_Object* pReferred =
- m_pDocument->GetOrParseIndirectObject(pRef->GetRefObjNum());
- if (pReferred)
- new_obj_array.Add(pReferred);
- }
- } break;
- }
- }
-
- if (count > 0) {
- for (int i = 0; i < new_obj_array.GetSize(); ++i) {
- CPDF_Object* pObj = new_obj_array[i];
- if (CPDF_Reference* pRef = pObj->AsReference()) {
- uint32_t dwNum = pRef->GetRefObjNum();
- if (!pdfium::ContainsKey(m_ObjectSet, dwNum))
- ret_array.Add(pObj);
- } else {
- ret_array.Add(pObj);
- }
- }
- return FALSE;
- }
-
- obj_array.RemoveAll();
- obj_array.Append(new_obj_array);
- return IsObjectsAvail(obj_array, FALSE, pHints, ret_array);
-}
-
-CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsDocAvail(
- DownloadHints* pHints) {
- if (!m_dwFileLen && m_pFileRead) {
- m_dwFileLen = (uint32_t)m_pFileRead->GetSize();
- if (!m_dwFileLen)
- return DataError;
- }
-
- while (!m_bDocAvail) {
- if (!CheckDocStatus(pHints))
- return DataNotAvailable;
- }
-
- return DataAvailable;
-}
-
-FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(DownloadHints* pHints) {
- if (!m_objs_array.GetSize()) {
- m_objs_array.RemoveAll();
- m_ObjectSet.clear();
- CFX_ArrayTemplate<CPDF_Object*> obj_array;
- obj_array.Append(m_arrayAcroforms);
- FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);
- if (bRet)
- m_objs_array.RemoveAll();
- return bRet;
- }
-
- CFX_ArrayTemplate<CPDF_Object*> new_objs_array;
- FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
- if (bRet) {
- int32_t iSize = m_arrayAcroforms.GetSize();
- for (int32_t i = 0; i < iSize; ++i) {
- m_arrayAcroforms.GetAt(i)->Release();
- }
- m_arrayAcroforms.RemoveAll();
- } else {
- m_objs_array.RemoveAll();
- m_objs_array.Append(new_objs_array);
- }
- return bRet;
-}
-
-FX_BOOL CPDF_DataAvail::CheckAcroForm(DownloadHints* pHints) {
- FX_BOOL bExist = FALSE;
- m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist);
- if (!bExist) {
- m_docStatus = PDF_DATAAVAIL_PAGETREE;
- return TRUE;
- }
-
- if (!m_pAcroForm) {
- if (m_docStatus == PDF_DATAAVAIL_ERROR) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return TRUE;
- }
- return FALSE;
- }
-
- m_arrayAcroforms.Add(m_pAcroForm);
- m_docStatus = PDF_DATAAVAIL_PAGETREE;
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckDocStatus(DownloadHints* pHints) {
- switch (m_docStatus) {
- case PDF_DATAAVAIL_HEADER:
- return CheckHeader(pHints);
- case PDF_DATAAVAIL_FIRSTPAGE:
- case PDF_DATAAVAIL_FIRSTPAGE_PREPARE:
- return CheckFirstPage(pHints);
- case PDF_DATAAVAIL_HINTTABLE:
- return CheckHintTables(pHints);
- case PDF_DATAAVAIL_END:
- return CheckEnd(pHints);
- case PDF_DATAAVAIL_CROSSREF:
- return CheckCrossRef(pHints);
- case PDF_DATAAVAIL_CROSSREF_ITEM:
- return CheckCrossRefItem(pHints);
- case PDF_DATAAVAIL_CROSSREF_STREAM:
- return CheckAllCrossRefStream(pHints);
- case PDF_DATAAVAIL_TRAILER:
- return CheckTrailer(pHints);
- case PDF_DATAAVAIL_TRAILER_APPEND:
- return CheckTrailerAppend(pHints);
- case PDF_DATAAVAIL_LOADALLCROSSREF:
- return LoadAllXref(pHints);
- case PDF_DATAAVAIL_LOADALLFILE:
- return LoadAllFile(pHints);
- case PDF_DATAAVAIL_ROOT:
- return CheckRoot(pHints);
- case PDF_DATAAVAIL_INFO:
- return CheckInfo(pHints);
- case PDF_DATAAVAIL_ACROFORM:
- return CheckAcroForm(pHints);
- case PDF_DATAAVAIL_PAGETREE:
- if (m_bTotalLoadPageTree)
- return CheckPages(pHints);
- return LoadDocPages(pHints);
- case PDF_DATAAVAIL_PAGE:
- if (m_bTotalLoadPageTree)
- return CheckPage(pHints);
- m_docStatus = PDF_DATAAVAIL_PAGE_LATERLOAD;
- return TRUE;
- case PDF_DATAAVAIL_ERROR:
- return LoadAllFile(pHints);
- case PDF_DATAAVAIL_PAGE_LATERLOAD:
- m_docStatus = PDF_DATAAVAIL_PAGE;
- default:
- m_bDocAvail = TRUE;
- return TRUE;
- }
-}
-
-FX_BOOL CPDF_DataAvail::CheckPageStatus(DownloadHints* pHints) {
- switch (m_docStatus) {
- case PDF_DATAAVAIL_PAGETREE:
- return CheckPages(pHints);
- case PDF_DATAAVAIL_PAGE:
- return CheckPage(pHints);
- case PDF_DATAAVAIL_ERROR:
- return LoadAllFile(pHints);
- default:
- m_bPagesTreeLoad = TRUE;
- m_bPagesLoad = TRUE;
- return TRUE;
- }
-}
-
-FX_BOOL CPDF_DataAvail::LoadAllFile(DownloadHints* pHints) {
- if (m_pFileAvail->IsDataAvail(0, (uint32_t)m_dwFileLen)) {
- m_docStatus = PDF_DATAAVAIL_DONE;
- return TRUE;
- }
-
- pHints->AddSegment(0, (uint32_t)m_dwFileLen);
- return FALSE;
-}
-
-FX_BOOL CPDF_DataAvail::LoadAllXref(DownloadHints* pHints) {
- m_parser.m_pSyntax->InitParser(m_pFileRead, (uint32_t)m_dwHeaderOffset);
- m_parser.m_bOwnFileRead = false;
- if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) &&
- !m_parser.LoadAllCrossRefV5(m_dwLastXRefOffset)) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return FALSE;
- }
-
- m_dwRootObjNum = m_parser.GetRootObjNum();
- m_dwInfoObjNum = m_parser.GetInfoObjNum();
- m_pCurrentParser = &m_parser;
- m_docStatus = PDF_DATAAVAIL_ROOT;
- return TRUE;
-}
-
-CPDF_Object* CPDF_DataAvail::GetObject(uint32_t objnum,
- DownloadHints* pHints,
- FX_BOOL* pExistInFile) {
- CPDF_Object* pRet = nullptr;
- uint32_t size = 0;
- FX_FILESIZE offset = 0;
- CPDF_Parser* pParser = nullptr;
-
- if (pExistInFile)
- *pExistInFile = TRUE;
-
- if (m_pDocument) {
- size = GetObjectSize(objnum, offset);
- pParser = m_pDocument->GetParser();
- } else {
- size = (uint32_t)m_parser.GetObjectSize(objnum);
- offset = m_parser.GetObjectOffset(objnum);
- pParser = &m_parser;
- }
-
- if (!IsDataAvail(offset, size, pHints))
- return nullptr;
-
- if (pParser)
- pRet = pParser->ParseIndirectObject(nullptr, objnum);
-
- if (!pRet && pExistInFile)
- *pExistInFile = FALSE;
-
- return pRet;
-}
-
-FX_BOOL CPDF_DataAvail::CheckInfo(DownloadHints* pHints) {
- FX_BOOL bExist = FALSE;
- CPDF_Object* pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist);
- if (!bExist) {
- m_docStatus =
- (m_bHaveAcroForm ? PDF_DATAAVAIL_ACROFORM : PDF_DATAAVAIL_PAGETREE);
- return TRUE;
- }
-
- if (!pInfo) {
- if (m_docStatus == PDF_DATAAVAIL_ERROR) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return TRUE;
- }
-
- if (m_Pos == m_dwFileLen)
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- if (pInfo)
- pInfo->Release();
-
- m_docStatus =
- (m_bHaveAcroForm ? PDF_DATAAVAIL_ACROFORM : PDF_DATAAVAIL_PAGETREE);
-
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckRoot(DownloadHints* pHints) {
- FX_BOOL bExist = FALSE;
- m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist);
- if (!bExist) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return TRUE;
- }
-
- if (!m_pRoot) {
- if (m_docStatus == PDF_DATAAVAIL_ERROR) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return TRUE;
- }
- return FALSE;
- }
-
- CPDF_Dictionary* pDict = m_pRoot->GetDict();
- if (!pDict) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- CPDF_Reference* pRef = ToReference(pDict->GetObjectFor("Pages"));
- if (!pRef) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- m_PagesObjNum = pRef->GetRefObjNum();
- CPDF_Reference* pAcroFormRef =
- ToReference(m_pRoot->GetDict()->GetObjectFor("AcroForm"));
- if (pAcroFormRef) {
- m_bHaveAcroForm = TRUE;
- m_dwAcroFormObjNum = pAcroFormRef->GetRefObjNum();
- }
-
- if (m_dwInfoObjNum) {
- m_docStatus = PDF_DATAAVAIL_INFO;
- } else {
- m_docStatus =
- m_bHaveAcroForm ? PDF_DATAAVAIL_ACROFORM : PDF_DATAAVAIL_PAGETREE;
- }
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::PreparePageItem() {
- CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
- CPDF_Reference* pRef =
- ToReference(pRoot ? pRoot->GetObjectFor("Pages") : nullptr);
- if (!pRef) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- m_PagesObjNum = pRef->GetRefObjNum();
- m_pCurrentParser = m_pDocument->GetParser();
- m_docStatus = PDF_DATAAVAIL_PAGETREE;
- return TRUE;
-}
-
-bool CPDF_DataAvail::IsFirstCheck(uint32_t dwPage) {
- return m_pageMapCheckState.insert(dwPage).second;
-}
-
-void CPDF_DataAvail::ResetFirstCheck(uint32_t dwPage) {
- m_pageMapCheckState.erase(dwPage);
-}
-
-FX_BOOL CPDF_DataAvail::CheckPage(DownloadHints* pHints) {
- uint32_t iPageObjs = m_PageObjList.GetSize();
- CFX_ArrayTemplate<uint32_t> UnavailObjList;
- for (uint32_t i = 0; i < iPageObjs; ++i) {
- uint32_t dwPageObjNum = m_PageObjList.GetAt(i);
- FX_BOOL bExist = FALSE;
- CPDF_Object* pObj = GetObject(dwPageObjNum, pHints, &bExist);
- if (!pObj) {
- if (bExist)
- UnavailObjList.Add(dwPageObjNum);
- continue;
- }
-
- CPDF_Array* pArray = ToArray(pObj);
- if (pArray) {
- for (CPDF_Object* pArrayObj : *pArray) {
- if (CPDF_Reference* pRef = ToReference(pArrayObj))
- UnavailObjList.Add(pRef->GetRefObjNum());
- }
- }
-
- if (!pObj->IsDictionary()) {
- pObj->Release();
- continue;
- }
-
- CFX_ByteString type = pObj->GetDict()->GetStringFor("Type");
- if (type == "Pages") {
- m_PagesArray.Add(pObj);
- continue;
- }
- pObj->Release();
- }
-
- m_PageObjList.RemoveAll();
- if (UnavailObjList.GetSize()) {
- m_PageObjList.Append(UnavailObjList);
- return FALSE;
- }
-
- uint32_t iPages = m_PagesArray.GetSize();
- for (uint32_t i = 0; i < iPages; i++) {
- CPDF_Object* pPages = m_PagesArray.GetAt(i);
- if (!pPages)
- continue;
-
- if (!GetPageKids(m_pCurrentParser, pPages)) {
- pPages->Release();
- while (++i < iPages) {
- pPages = m_PagesArray.GetAt(i);
- pPages->Release();
- }
- m_PagesArray.RemoveAll();
-
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
- pPages->Release();
- }
-
- m_PagesArray.RemoveAll();
- if (!m_PageObjList.GetSize())
- m_docStatus = PDF_DATAAVAIL_DONE;
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages) {
- if (!pParser) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- CPDF_Dictionary* pDict = pPages->GetDict();
- CPDF_Object* pKids = pDict ? pDict->GetObjectFor("Kids") : nullptr;
- if (!pKids)
- return TRUE;
-
- switch (pKids->GetType()) {
- case CPDF_Object::REFERENCE:
- m_PageObjList.Add(pKids->AsReference()->GetRefObjNum());
- break;
- case CPDF_Object::ARRAY: {
- CPDF_Array* pKidsArray = pKids->AsArray();
- for (size_t i = 0; i < pKidsArray->GetCount(); ++i) {
- if (CPDF_Reference* pRef = ToReference(pKidsArray->GetObjectAt(i)))
- m_PageObjList.Add(pRef->GetRefObjNum());
- }
- } break;
- default:
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckPages(DownloadHints* pHints) {
- FX_BOOL bExist = FALSE;
- CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist);
- if (!bExist) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return TRUE;
- }
-
- if (!pPages) {
- if (m_docStatus == PDF_DATAAVAIL_ERROR) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return TRUE;
- }
- return FALSE;
- }
-
- if (!GetPageKids(m_pCurrentParser, pPages)) {
- pPages->Release();
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- pPages->Release();
- m_docStatus = PDF_DATAAVAIL_PAGE;
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckHeader(DownloadHints* pHints) {
- ASSERT(m_dwFileLen >= 0);
- const uint32_t kReqSize = std::min(static_cast<uint32_t>(m_dwFileLen), 1024U);
-
- if (m_pFileAvail->IsDataAvail(0, kReqSize)) {
- uint8_t buffer[1024];
- m_pFileRead->ReadBlock(buffer, 0, kReqSize);
-
- if (IsLinearizedFile(buffer, kReqSize)) {
- m_docStatus = PDF_DATAAVAIL_FIRSTPAGE;
- } else {
- if (m_docStatus == PDF_DATAAVAIL_ERROR)
- return FALSE;
- m_docStatus = PDF_DATAAVAIL_END;
- }
- return TRUE;
- }
-
- pHints->AddSegment(0, kReqSize);
- return FALSE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckFirstPage(DownloadHints* pHints) {
- CPDF_Dictionary* pDict = m_pLinearized->GetDict();
- CPDF_Object* pEndOffSet = pDict ? pDict->GetObjectFor("E") : nullptr;
- if (!pEndOffSet) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- CPDF_Object* pXRefOffset = pDict ? pDict->GetObjectFor("T") : nullptr;
- if (!pXRefOffset) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- CPDF_Object* pFileLen = pDict ? pDict->GetObjectFor("L") : nullptr;
- if (!pFileLen) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- FX_BOOL bNeedDownLoad = FALSE;
- if (pEndOffSet->IsNumber()) {
- uint32_t dwEnd = pEndOffSet->GetInteger();
- dwEnd += 512;
- if ((FX_FILESIZE)dwEnd > m_dwFileLen)
- dwEnd = (uint32_t)m_dwFileLen;
-
- int32_t iStartPos = (int32_t)(m_dwFileLen > 1024 ? 1024 : m_dwFileLen);
- int32_t iSize = dwEnd > 1024 ? dwEnd - 1024 : 0;
- if (!m_pFileAvail->IsDataAvail(iStartPos, iSize)) {
- pHints->AddSegment(iStartPos, iSize);
- bNeedDownLoad = TRUE;
- }
- }
-
- m_dwLastXRefOffset = 0;
- FX_FILESIZE dwFileLen = 0;
- if (pXRefOffset->IsNumber())
- m_dwLastXRefOffset = pXRefOffset->GetInteger();
-
- if (pFileLen->IsNumber())
- dwFileLen = pFileLen->GetInteger();
-
- if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset,
- (uint32_t)(dwFileLen - m_dwLastXRefOffset))) {
- if (m_docStatus == PDF_DATAAVAIL_FIRSTPAGE) {
- uint32_t dwSize = (uint32_t)(dwFileLen - m_dwLastXRefOffset);
- FX_FILESIZE offset = m_dwLastXRefOffset;
- if (dwSize < 512 && dwFileLen > 512) {
- dwSize = 512;
- offset = dwFileLen - 512;
- }
- pHints->AddSegment(offset, dwSize);
- }
- } else {
- m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
- }
-
- if (bNeedDownLoad || m_docStatus != PDF_DATAAVAIL_FIRSTPAGE_PREPARE) {
- m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;
- return FALSE;
- }
-
- m_docStatus =
- m_bSupportHintTable ? PDF_DATAAVAIL_HINTTABLE : PDF_DATAAVAIL_DONE;
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::IsDataAvail(FX_FILESIZE offset,
- uint32_t size,
- DownloadHints* pHints) {
- if (offset < 0 || offset > m_dwFileLen)
- return TRUE;
-
- FX_SAFE_FILESIZE safeSize = offset;
- safeSize += size;
- safeSize += 512;
- if (!safeSize.IsValid() || safeSize.ValueOrDie() > m_dwFileLen)
- size = m_dwFileLen - offset;
- else
- size += 512;
-
- if (!m_pFileAvail->IsDataAvail(offset, size)) {
- pHints->AddSegment(offset, size);
- return FALSE;
- }
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckHintTables(DownloadHints* pHints) {
- CPDF_Dictionary* pDict = m_pLinearized->GetDict();
- if (!pDict) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- // The actual value is not required here, but validate its existence and type.
- CPDF_Number* pFirstPage = ToNumber(pDict->GetDirectObjectFor("O"));
- if (!pFirstPage || !pFirstPage->IsInteger()) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- CPDF_Number* pPageCount = ToNumber(pDict->GetDirectObjectFor("N"));
- if (!pPageCount || !pPageCount->IsInteger()) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- int nPageCount = pPageCount->GetInteger();
- if (nPageCount <= 1) {
- m_docStatus = PDF_DATAAVAIL_DONE;
- return TRUE;
- }
-
- CPDF_Array* pHintStreamRange = pDict->GetArrayFor("H");
- size_t nHintStreamSize = pHintStreamRange ? pHintStreamRange->GetCount() : 0;
- if (nHintStreamSize != 2 && nHintStreamSize != 4) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- for (const CPDF_Object* pArrayObject : *pHintStreamRange) {
- const CPDF_Number* pNumber = ToNumber(pArrayObject->GetDirect());
- if (!pNumber || !pNumber->IsInteger()) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
- }
-
- FX_FILESIZE szHintStart = pHintStreamRange->GetIntegerAt(0);
- FX_FILESIZE szHintLength = pHintStreamRange->GetIntegerAt(1);
- if (szHintStart < 0 || szHintLength <= 0) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- if (!IsDataAvail(szHintStart, szHintLength, pHints))
- return FALSE;
-
- m_syntaxParser.InitParser(m_pFileRead, m_dwHeaderOffset);
-
- std::unique_ptr<CPDF_HintTables> pHintTables(
- new CPDF_HintTables(this, pDict));
- std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pHintStream(
- ParseIndirectObjectAt(szHintStart, 0));
- CPDF_Stream* pStream = ToStream(pHintStream.get());
- if (pStream && pHintTables->LoadHintStream(pStream))
- m_pHintTables = std::move(pHintTables);
-
- m_docStatus = PDF_DATAAVAIL_DONE;
- return TRUE;
-}
-
-CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt(
- FX_FILESIZE pos,
- uint32_t objnum,
- CPDF_IndirectObjectHolder* pObjList) {
- FX_FILESIZE SavedPos = m_syntaxParser.SavePos();
- m_syntaxParser.RestorePos(pos);
-
- bool bIsNumber;
- CFX_ByteString word = m_syntaxParser.GetNextWord(&bIsNumber);
- if (!bIsNumber)
- return nullptr;
-
- uint32_t parser_objnum = FXSYS_atoui(word.c_str());
- if (objnum && parser_objnum != objnum)
- return nullptr;
-
- word = m_syntaxParser.GetNextWord(&bIsNumber);
- if (!bIsNumber)
- return nullptr;
-
- uint32_t gennum = FXSYS_atoui(word.c_str());
- if (m_syntaxParser.GetKeyword() != "obj") {
- m_syntaxParser.RestorePos(SavedPos);
- return nullptr;
- }
-
- CPDF_Object* pObj =
- m_syntaxParser.GetObject(pObjList, parser_objnum, gennum, true);
- m_syntaxParser.RestorePos(SavedPos);
- return pObj;
-}
-
-CPDF_DataAvail::DocLinearizationStatus CPDF_DataAvail::IsLinearizedPDF() {
- const uint32_t kReqSize = 1024;
- if (!m_pFileAvail->IsDataAvail(0, kReqSize))
- return LinearizationUnknown;
-
- if (!m_pFileRead)
- return NotLinearized;
-
- FX_FILESIZE dwSize = m_pFileRead->GetSize();
- if (dwSize < (FX_FILESIZE)kReqSize)
- return LinearizationUnknown;
-
- uint8_t buffer[1024];
- m_pFileRead->ReadBlock(buffer, 0, kReqSize);
- if (IsLinearizedFile(buffer, kReqSize))
- return Linearized;
-
- return NotLinearized;
-}
-
-FX_BOOL CPDF_DataAvail::IsLinearized() {
- return m_bLinearized;
-}
-
-FX_BOOL CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, uint32_t dwLen) {
- if (m_pLinearized)
- return m_bLinearized;
-
- ScopedFileStream file(FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE));
-
- int32_t offset = GetHeaderOffset(file.get());
- if (offset == -1) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- m_dwHeaderOffset = offset;
- m_syntaxParser.InitParser(file.get(), offset);
- m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9);
-
- bool bNumber;
- CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(&bNumber);
- if (!bNumber)
- return FALSE;
-
- uint32_t objnum = FXSYS_atoui(wordObjNum.c_str());
- m_pLinearized =
- ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum);
- if (!m_pLinearized)
- return FALSE;
-
- CPDF_Dictionary* pDict = m_pLinearized->GetDict();
- if (!pDict || !pDict->GetObjectFor("Linearized"))
- return FALSE;
-
- CPDF_Object* pLen = pDict->GetObjectFor("L");
- if (!pLen)
- return FALSE;
-
- if ((FX_FILESIZE)pLen->GetInteger() != m_pFileRead->GetSize())
- return FALSE;
-
- m_bLinearized = TRUE;
-
- if (CPDF_Number* pNo = ToNumber(pDict->GetObjectFor("P")))
- m_dwFirstPageNo = pNo->GetInteger();
-
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckEnd(DownloadHints* pHints) {
- uint32_t req_pos = (uint32_t)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0);
- uint32_t dwSize = (uint32_t)(m_dwFileLen - req_pos);
-
- if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) {
- uint8_t buffer[1024];
- m_pFileRead->ReadBlock(buffer, req_pos, dwSize);
-
- ScopedFileStream file(FX_CreateMemoryStream(buffer, (size_t)dwSize, FALSE));
- m_syntaxParser.InitParser(file.get(), 0);
- m_syntaxParser.RestorePos(dwSize - 1);
-
- if (m_syntaxParser.SearchWord("startxref", TRUE, FALSE, dwSize)) {
- m_syntaxParser.GetNextWord(nullptr);
-
- bool bNumber;
- CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(&bNumber);
- if (!bNumber) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str.c_str());
- if (!m_dwXRefOffset || m_dwXRefOffset > m_dwFileLen) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return TRUE;
- }
-
- m_dwLastXRefOffset = m_dwXRefOffset;
- SetStartOffset(m_dwXRefOffset);
- m_docStatus = PDF_DATAAVAIL_CROSSREF;
- return TRUE;
- }
-
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return TRUE;
- }
-
- pHints->AddSegment(req_pos, dwSize);
- return FALSE;
-}
-
-int32_t CPDF_DataAvail::CheckCrossRefStream(DownloadHints* pHints,
- FX_FILESIZE& xref_offset) {
- xref_offset = 0;
- uint32_t req_size =
- (uint32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
-
- if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) {
- int32_t iSize = (int32_t)(m_Pos + req_size - m_dwCurrentXRefSteam);
- CFX_BinaryBuf buf(iSize);
- uint8_t* pBuf = buf.GetBuffer();
-
- m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize);
-
- ScopedFileStream file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE));
- m_parser.m_pSyntax->InitParser(file.get(), 0);
-
- bool bNumber;
- CFX_ByteString objnum = m_parser.m_pSyntax->GetNextWord(&bNumber);
- if (!bNumber)
- return -1;
-
- uint32_t objNum = FXSYS_atoui(objnum.c_str());
- CPDF_Object* pObj = m_parser.ParseIndirectObjectAt(nullptr, 0, objNum);
- if (!pObj) {
- m_Pos += m_parser.m_pSyntax->SavePos();
- return 0;
- }
-
- CPDF_Dictionary* pDict = pObj->GetDict();
- CPDF_Name* pName = ToName(pDict ? pDict->GetObjectFor("Type") : nullptr);
- if (pName) {
- if (pName->GetString() == "XRef") {
- m_Pos += m_parser.m_pSyntax->SavePos();
- xref_offset = pObj->GetDict()->GetIntegerFor("Prev");
- pObj->Release();
- return 1;
- }
- }
- pObj->Release();
- return -1;
- }
- pHints->AddSegment(m_Pos, req_size);
- return 0;
-}
-
-void CPDF_DataAvail::SetStartOffset(FX_FILESIZE dwOffset) {
- m_Pos = dwOffset;
-}
-
-FX_BOOL CPDF_DataAvail::GetNextToken(CFX_ByteString& token) {
- uint8_t ch;
- if (!GetNextChar(ch))
- return FALSE;
-
- while (1) {
- while (PDFCharIsWhitespace(ch)) {
- if (!GetNextChar(ch))
- return FALSE;
- }
-
- if (ch != '%')
- break;
-
- while (1) {
- if (!GetNextChar(ch))
- return FALSE;
- if (PDFCharIsLineEnding(ch))
- break;
- }
- }
-
- uint8_t buffer[256];
- uint32_t index = 0;
- if (PDFCharIsDelimiter(ch)) {
- buffer[index++] = ch;
- if (ch == '/') {
- while (1) {
- if (!GetNextChar(ch))
- return FALSE;
-
- if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) {
- m_Pos--;
- CFX_ByteString ret(buffer, index);
- token = ret;
- return TRUE;
- }
-
- if (index < sizeof(buffer))
- buffer[index++] = ch;
- }
- } else if (ch == '<') {
- if (!GetNextChar(ch))
- return FALSE;
-
- if (ch == '<')
- buffer[index++] = ch;
- else
- m_Pos--;
- } else if (ch == '>') {
- if (!GetNextChar(ch))
- return FALSE;
-
- if (ch == '>')
- buffer[index++] = ch;
- else
- m_Pos--;
- }
-
- CFX_ByteString ret(buffer, index);
- token = ret;
- return TRUE;
- }
-
- while (1) {
- if (index < sizeof(buffer))
- buffer[index++] = ch;
-
- if (!GetNextChar(ch))
- return FALSE;
-
- if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) {
- m_Pos--;
- break;
- }
- }
-
- token = CFX_ByteString(buffer, index);
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::GetNextChar(uint8_t& ch) {
- FX_FILESIZE pos = m_Pos;
- if (pos >= m_dwFileLen)
- return FALSE;
-
- if (m_bufferOffset >= pos ||
- (FX_FILESIZE)(m_bufferOffset + m_bufferSize) <= pos) {
- FX_FILESIZE read_pos = pos;
- uint32_t read_size = 512;
- if ((FX_FILESIZE)read_size > m_dwFileLen)
- read_size = (uint32_t)m_dwFileLen;
-
- if ((FX_FILESIZE)(read_pos + read_size) > m_dwFileLen)
- read_pos = m_dwFileLen - read_size;
-
- if (!m_pFileRead->ReadBlock(m_bufferData, read_pos, read_size))
- return FALSE;
-
- m_bufferOffset = read_pos;
- m_bufferSize = read_size;
- }
- ch = m_bufferData[pos - m_bufferOffset];
- m_Pos++;
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckCrossRefItem(DownloadHints* pHints) {
- int32_t iSize = 0;
- CFX_ByteString token;
- while (1) {
- if (!GetNextToken(token)) {
- iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
- pHints->AddSegment(m_Pos, iSize);
- return FALSE;
- }
-
- if (token == "trailer") {
- m_dwTrailerOffset = m_Pos;
- m_docStatus = PDF_DATAAVAIL_TRAILER;
- return TRUE;
- }
- }
-}
-
-FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(DownloadHints* pHints) {
- FX_FILESIZE xref_offset = 0;
-
- int32_t nRet = CheckCrossRefStream(pHints, xref_offset);
- if (nRet == 1) {
- if (!xref_offset) {
- m_docStatus = PDF_DATAAVAIL_LOADALLCROSSREF;
- } else {
- m_dwCurrentXRefSteam = xref_offset;
- m_Pos = xref_offset;
- }
- return TRUE;
- }
-
- if (nRet == -1)
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckCrossRef(DownloadHints* pHints) {
- int32_t iSize = 0;
- CFX_ByteString token;
- if (!GetNextToken(token)) {
- iSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
- pHints->AddSegment(m_Pos, iSize);
- return FALSE;
- }
-
- if (token == "xref") {
- while (1) {
- if (!GetNextToken(token)) {
- iSize =
- (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
- pHints->AddSegment(m_Pos, iSize);
- m_docStatus = PDF_DATAAVAIL_CROSSREF_ITEM;
- return FALSE;
- }
-
- if (token == "trailer") {
- m_dwTrailerOffset = m_Pos;
- m_docStatus = PDF_DATAAVAIL_TRAILER;
- return TRUE;
- }
- }
- } else {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return TRUE;
- }
- return FALSE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckTrailerAppend(DownloadHints* pHints) {
- if (m_Pos < m_dwFileLen) {
- FX_FILESIZE dwAppendPos = m_Pos + m_syntaxParser.SavePos();
- int32_t iSize = (int32_t)(
- dwAppendPos + 512 > m_dwFileLen ? m_dwFileLen - dwAppendPos : 512);
-
- if (!m_pFileAvail->IsDataAvail(dwAppendPos, iSize)) {
- pHints->AddSegment(dwAppendPos, iSize);
- return FALSE;
- }
- }
-
- if (m_dwPrevXRefOffset) {
- SetStartOffset(m_dwPrevXRefOffset);
- m_docStatus = PDF_DATAAVAIL_CROSSREF;
- } else {
- m_docStatus = PDF_DATAAVAIL_LOADALLCROSSREF;
- }
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckTrailer(DownloadHints* pHints) {
- int32_t iTrailerSize =
- (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);
- if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) {
- int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset);
- CFX_BinaryBuf buf(iSize);
- uint8_t* pBuf = buf.GetBuffer();
- if (!pBuf) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize))
- return FALSE;
-
- ScopedFileStream file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE));
- m_syntaxParser.InitParser(file.get(), 0);
-
- std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pTrailer(
- m_syntaxParser.GetObject(nullptr, 0, 0, true));
- if (!pTrailer) {
- m_Pos += m_syntaxParser.SavePos();
- pHints->AddSegment(m_Pos, iTrailerSize);
- return FALSE;
- }
-
- if (!pTrailer->IsDictionary())
- return FALSE;
-
- CPDF_Dictionary* pTrailerDict = pTrailer->GetDict();
- CPDF_Object* pEncrypt = pTrailerDict->GetObjectFor("Encrypt");
- if (ToReference(pEncrypt)) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- return TRUE;
- }
-
- uint32_t xrefpos = GetDirectInteger(pTrailerDict, "Prev");
- if (xrefpos) {
- m_dwPrevXRefOffset = GetDirectInteger(pTrailerDict, "XRefStm");
- if (m_dwPrevXRefOffset) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- } else {
- m_dwPrevXRefOffset = xrefpos;
- if (m_dwPrevXRefOffset >= m_dwFileLen) {
- m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
- } else {
- SetStartOffset(m_dwPrevXRefOffset);
- m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;
- }
- }
- return TRUE;
- }
- m_dwPrevXRefOffset = 0;
- m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;
- return TRUE;
- }
- pHints->AddSegment(m_Pos, iTrailerSize);
- return FALSE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckPage(uint32_t dwPage, DownloadHints* pHints) {
- while (TRUE) {
- switch (m_docStatus) {
- case PDF_DATAAVAIL_PAGETREE:
- if (!LoadDocPages(pHints))
- return FALSE;
- break;
- case PDF_DATAAVAIL_PAGE:
- if (!LoadDocPage(dwPage, pHints))
- return FALSE;
- break;
- case PDF_DATAAVAIL_ERROR:
- return LoadAllFile(pHints);
- default:
- m_bPagesTreeLoad = TRUE;
- m_bPagesLoad = TRUE;
- m_bCurPageDictLoadOK = TRUE;
- m_docStatus = PDF_DATAAVAIL_PAGE;
- return TRUE;
- }
- }
-}
-
-FX_BOOL CPDF_DataAvail::CheckArrayPageNode(uint32_t dwPageNo,
- PageNode* pPageNode,
- DownloadHints* pHints) {
- FX_BOOL bExist = FALSE;
- CPDF_Object* pPages = GetObject(dwPageNo, pHints, &bExist);
- if (!bExist) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- if (!pPages) {
- if (m_docStatus == PDF_DATAAVAIL_ERROR) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
- return FALSE;
- }
-
- CPDF_Array* pArray = pPages->AsArray();
- if (!pArray) {
- pPages->Release();
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- pPageNode->m_type = PDF_PAGENODE_PAGES;
- for (size_t i = 0; i < pArray->GetCount(); ++i) {
- CPDF_Reference* pKid = ToReference(pArray->GetObjectAt(i));
- if (!pKid)
- continue;
-
- PageNode* pNode = new PageNode();
- pPageNode->m_childNode.Add(pNode);
- pNode->m_dwPageNo = pKid->GetRefObjNum();
- }
- pPages->Release();
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(uint32_t dwPageNo,
- PageNode* pPageNode,
- DownloadHints* pHints) {
- FX_BOOL bExist = FALSE;
- CPDF_Object* pPage = GetObject(dwPageNo, pHints, &bExist);
- if (!bExist) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- if (!pPage) {
- if (m_docStatus == PDF_DATAAVAIL_ERROR)
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- if (pPage->IsArray()) {
- pPageNode->m_dwPageNo = dwPageNo;
- pPageNode->m_type = PDF_PAGENODE_ARRAY;
- pPage->Release();
- return TRUE;
- }
-
- if (!pPage->IsDictionary()) {
- pPage->Release();
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- pPageNode->m_dwPageNo = dwPageNo;
- CPDF_Dictionary* pDict = pPage->GetDict();
- CFX_ByteString type = pDict->GetStringFor("Type");
- if (type == "Pages") {
- pPageNode->m_type = PDF_PAGENODE_PAGES;
- CPDF_Object* pKids = pDict->GetObjectFor("Kids");
- if (!pKids) {
- m_docStatus = PDF_DATAAVAIL_PAGE;
- return TRUE;
- }
-
- switch (pKids->GetType()) {
- case CPDF_Object::REFERENCE: {
- CPDF_Reference* pKid = pKids->AsReference();
- PageNode* pNode = new PageNode();
- pPageNode->m_childNode.Add(pNode);
- pNode->m_dwPageNo = pKid->GetRefObjNum();
- } break;
- case CPDF_Object::ARRAY: {
- CPDF_Array* pKidsArray = pKids->AsArray();
- for (size_t i = 0; i < pKidsArray->GetCount(); ++i) {
- CPDF_Reference* pKid = ToReference(pKidsArray->GetObjectAt(i));
- if (!pKid)
- continue;
-
- PageNode* pNode = new PageNode();
- pPageNode->m_childNode.Add(pNode);
- pNode->m_dwPageNo = pKid->GetRefObjNum();
- }
- } break;
- default:
- break;
- }
- } else if (type == "Page") {
- pPageNode->m_type = PDF_PAGENODE_PAGE;
- } else {
- pPage->Release();
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
- pPage->Release();
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_DataAvail::PageNode& pageNodes,
- int32_t iPage,
- int32_t& iCount,
- DownloadHints* pHints,
- int level) {
- if (level >= kMaxPageRecursionDepth)
- return FALSE;
-
- int32_t iSize = pageNodes.m_childNode.GetSize();
- if (iSize <= 0 || iPage >= iSize) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- for (int32_t i = 0; i < iSize; ++i) {
- PageNode* pNode = pageNodes.m_childNode.GetAt(i);
- if (!pNode)
- continue;
-
- switch (pNode->m_type) {
- case PDF_PAGENODE_UNKNOWN:
- if (!CheckUnkownPageNode(pNode->m_dwPageNo, pNode, pHints)) {
- return FALSE;
- }
- --i;
- break;
- case PDF_PAGENODE_PAGE:
- iCount++;
- if (iPage == iCount && m_pDocument)
- m_pDocument->SetPageObjNum(iPage, pNode->m_dwPageNo);
- break;
- case PDF_PAGENODE_PAGES:
- if (!CheckPageNode(*pNode, iPage, iCount, pHints, level + 1))
- return FALSE;
- break;
- case PDF_PAGENODE_ARRAY:
- if (!CheckArrayPageNode(pNode->m_dwPageNo, pNode, pHints))
- return FALSE;
- --i;
- break;
- }
-
- if (iPage == iCount) {
- m_docStatus = PDF_DATAAVAIL_DONE;
- return TRUE;
- }
- }
- return TRUE;
-}
-
-FX_BOOL CPDF_DataAvail::LoadDocPage(uint32_t dwPage, DownloadHints* pHints) {
- FX_SAFE_INT32 safePage = pdfium::base::checked_cast<int32_t>(dwPage);
- int32_t iPage = safePage.ValueOrDie();
- if (m_pDocument->GetPageCount() <= iPage ||
- m_pDocument->IsPageLoaded(iPage)) {
- m_docStatus = PDF_DATAAVAIL_DONE;
- return TRUE;
- }
-
- if (m_pageNodes.m_type == PDF_PAGENODE_PAGE) {
- if (iPage == 0) {
- m_docStatus = PDF_DATAAVAIL_DONE;
- return TRUE;
- }
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return TRUE;
- }
- int32_t iCount = -1;
- return CheckPageNode(m_pageNodes, iPage, iCount, pHints, 0);
-}
-
-FX_BOOL CPDF_DataAvail::CheckPageCount(DownloadHints* pHints) {
- FX_BOOL bExist = FALSE;
- CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist);
- if (!bExist) {
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- if (!pPages)
- return FALSE;
-
- CPDF_Dictionary* pPagesDict = pPages->GetDict();
- if (!pPagesDict) {
- pPages->Release();
- m_docStatus = PDF_DATAAVAIL_ERROR;
- return FALSE;
- }
-
- if (!pPagesDict->KeyExist("Kids")) {
- pPages->Release();
- return TRUE;
- }
-
- int count = pPagesDict->GetIntegerFor("Count");
- if (count > 0) {
- pPages->Release();
- return TRUE;
- }
-
- pPages->Release();
- return FALSE;
-}
-
-FX_BOOL CPDF_DataAvail::LoadDocPages(DownloadHints* pHints) {
- if (!CheckUnkownPageNode(m_PagesObjNum, &m_pageNodes, pHints))
- return FALSE;
-
- if (CheckPageCount(pHints)) {
- m_docStatus = PDF_DATAAVAIL_PAGE;
- return TRUE;
- }
-
- m_bTotalLoadPageTree = TRUE;
- return FALSE;
-}
-
-FX_BOOL CPDF_DataAvail::LoadPages(DownloadHints* pHints) {
- while (!m_bPagesTreeLoad) {
- if (!CheckPageStatus(pHints))
- return FALSE;
- }
-
- if (m_bPagesLoad)
- return TRUE;
-
- m_pDocument->LoadPages();
- return FALSE;
-}
-
-CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckLinearizedData(
- DownloadHints* pHints) {
- if (m_bLinearedDataOK)
- return DataAvailable;
-
- if (!m_bMainXRefLoadTried) {
- FX_SAFE_UINT32 data_size = m_dwFileLen;
- data_size -= m_dwLastXRefOffset;
- if (!data_size.IsValid())
- return DataError;
-
- if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset,
- data_size.ValueOrDie())) {
- pHints->AddSegment(m_dwLastXRefOffset, data_size.ValueOrDie());
- return DataNotAvailable;
- }
-
- CPDF_Parser::Error eRet =
- m_pDocument->GetParser()->LoadLinearizedMainXRefTable();
- m_bMainXRefLoadTried = TRUE;
- if (eRet != CPDF_Parser::SUCCESS)
- return DataError;
-
- if (!PreparePageItem())
- return DataNotAvailable;
-
- m_bMainXRefLoadedOK = TRUE;
- m_bLinearedDataOK = TRUE;
- }
-
- return m_bLinearedDataOK ? DataAvailable : DataNotAvailable;
-}
-
-FX_BOOL CPDF_DataAvail::CheckPageAnnots(uint32_t dwPage,
- DownloadHints* pHints) {
- if (!m_objs_array.GetSize()) {
- m_objs_array.RemoveAll();
- m_ObjectSet.clear();
-
- FX_SAFE_INT32 safePage = pdfium::base::checked_cast<int32_t>(dwPage);
- CPDF_Dictionary* pPageDict = m_pDocument->GetPage(safePage.ValueOrDie());
- if (!pPageDict)
- return TRUE;
-
- CPDF_Object* pAnnots = pPageDict->GetObjectFor("Annots");
- if (!pAnnots)
- return TRUE;
-
- CFX_ArrayTemplate<CPDF_Object*> obj_array;
- obj_array.Add(pAnnots);
-
- FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);
- if (bRet)
- m_objs_array.RemoveAll();
-
- return bRet;
- }
-
- CFX_ArrayTemplate<CPDF_Object*> new_objs_array;
- FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
- m_objs_array.RemoveAll();
- if (!bRet)
- m_objs_array.Append(new_objs_array);
-
- return bRet;
-}
-
-CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckLinearizedFirstPage(
- uint32_t dwPage,
- DownloadHints* pHints) {
- if (!m_bAnnotsLoad) {
- if (!CheckPageAnnots(dwPage, pHints))
- return DataNotAvailable;
- m_bAnnotsLoad = TRUE;
- }
-
- DocAvailStatus nRet = CheckLinearizedData(pHints);
- if (nRet == DataAvailable)
- m_bPageLoadedOK = FALSE;
- return nRet;
-}
-
-FX_BOOL CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary* pDict) {
- CFX_AutoRestorer<int> restorer(&s_CurrentDataAvailRecursionDepth);
- if (++s_CurrentDataAvailRecursionDepth > kMaxDataAvailRecursionDepth)
- return FALSE;
-
- CPDF_Object* pParent = pDict->GetObjectFor("Parent");
- if (!pParent)
- return FALSE;
-
- CPDF_Dictionary* pParentDict = pParent->GetDict();
- if (!pParentDict)
- return FALSE;
-
- CPDF_Object* pRet = pParentDict->GetObjectFor("Resources");
- if (pRet) {
- m_pPageResource = pRet;
- return TRUE;
- }
-
- return HaveResourceAncestor(pParentDict);
-}
-
-CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::IsPageAvail(
- uint32_t dwPage,
- DownloadHints* pHints) {
- if (!m_pDocument)
- return DataError;
-
- if (IsFirstCheck(dwPage)) {
- m_bCurPageDictLoadOK = FALSE;
- m_bPageLoadedOK = FALSE;
- m_bAnnotsLoad = FALSE;
- m_bNeedDownLoadResource = FALSE;
- m_objs_array.RemoveAll();
- m_ObjectSet.clear();
- }
-
- if (pdfium::ContainsKey(m_pagesLoadState, dwPage))
- return DataAvailable;
-
- if (m_bLinearized) {
- if (dwPage == m_dwFirstPageNo) {
- DocAvailStatus nRet = CheckLinearizedFirstPage(dwPage, pHints);
- if (nRet == DataAvailable)
- m_pagesLoadState.insert(dwPage);
- return nRet;
- }
-
- DocAvailStatus nResult = CheckLinearizedData(pHints);
- if (nResult != DataAvailable)
- return nResult;
-
- if (m_pHintTables) {
- nResult = m_pHintTables->CheckPage(dwPage, pHints);
- if (nResult != DataAvailable)
- return nResult;
- m_pagesLoadState.insert(dwPage);
- return DataAvailable;
- }
-
- if (m_bMainXRefLoadedOK) {
- if (m_bTotalLoadPageTree) {
- if (!LoadPages(pHints))
- return DataNotAvailable;
- } else {
- if (!m_bCurPageDictLoadOK && !CheckPage(dwPage, pHints))
- return DataNotAvailable;
- }
- } else {
- if (!LoadAllFile(pHints))
- return DataNotAvailable;
- m_pDocument->GetParser()->RebuildCrossRef();
- ResetFirstCheck(dwPage);
- return DataAvailable;
- }
- } else {
- if (!m_bTotalLoadPageTree && !m_bCurPageDictLoadOK &&
- !CheckPage(dwPage, pHints)) {
- return DataNotAvailable;
- }
- }
-
- if (m_bHaveAcroForm && !m_bAcroFormLoad) {
- if (!CheckAcroFormSubObject(pHints))
- return DataNotAvailable;
- m_bAcroFormLoad = TRUE;
- }
-
- if (!m_bPageLoadedOK) {
- if (!m_objs_array.GetSize()) {
- m_objs_array.RemoveAll();
- m_ObjectSet.clear();
-
- FX_SAFE_INT32 safePage = pdfium::base::checked_cast<int32_t>(dwPage);
- m_pPageDict = m_pDocument->GetPage(safePage.ValueOrDie());
- if (!m_pPageDict) {
- ResetFirstCheck(dwPage);
- return DataAvailable;
- }
-
- CFX_ArrayTemplate<CPDF_Object*> obj_array;
- obj_array.Add(m_pPageDict);
- FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array);
- if (!bRet)
- return DataNotAvailable;
-
- m_objs_array.RemoveAll();
- } else {
- CFX_ArrayTemplate<CPDF_Object*> new_objs_array;
- FX_BOOL bRet =
- IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
-
- m_objs_array.RemoveAll();
- if (!bRet) {
- m_objs_array.Append(new_objs_array);
- return DataNotAvailable;
- }
- }
- m_bPageLoadedOK = TRUE;
- }
-
- if (!m_bAnnotsLoad) {
- if (!CheckPageAnnots(dwPage, pHints))
- return DataNotAvailable;
- m_bAnnotsLoad = TRUE;
- }
-
- if (m_pPageDict && !m_bNeedDownLoadResource) {
- m_pPageResource = m_pPageDict->GetObjectFor("Resources");
- m_bNeedDownLoadResource =
- m_pPageResource || HaveResourceAncestor(m_pPageDict);
- }
-
- if (m_bNeedDownLoadResource) {
- if (!CheckResources(pHints))
- return DataNotAvailable;
- m_bNeedDownLoadResource = FALSE;
- }
-
- m_bPageLoadedOK = FALSE;
- m_bAnnotsLoad = FALSE;
- m_bCurPageDictLoadOK = FALSE;
-
- ResetFirstCheck(dwPage);
- m_pagesLoadState.insert(dwPage);
- return DataAvailable;
-}
-
-FX_BOOL CPDF_DataAvail::CheckResources(DownloadHints* pHints) {
- if (!m_objs_array.GetSize()) {
- m_objs_array.RemoveAll();
- CFX_ArrayTemplate<CPDF_Object*> obj_array;
- obj_array.Add(m_pPageResource);
-
- FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array);
- if (bRet)
- m_objs_array.RemoveAll();
- return bRet;
- }
-
- CFX_ArrayTemplate<CPDF_Object*> new_objs_array;
- FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
- m_objs_array.RemoveAll();
- if (!bRet)
- m_objs_array.Append(new_objs_array);
- return bRet;
-}
-
-void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE* pPos,
- uint32_t* pSize) {
- if (pPos)
- *pPos = m_dwLastXRefOffset;
- if (pSize)
- *pSize = (uint32_t)(m_dwFileLen - m_dwLastXRefOffset);
-}
-
-int CPDF_DataAvail::GetPageCount() const {
- if (m_pLinearized) {
- CPDF_Dictionary* pDict = m_pLinearized->GetDict();
- CPDF_Object* pObj = pDict ? pDict->GetDirectObjectFor("N") : nullptr;
- return pObj ? pObj->GetInteger() : 0;
- }
- return m_pDocument ? m_pDocument->GetPageCount() : 0;
-}
-
-CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) {
- if (!m_pDocument || index < 0 || index >= GetPageCount())
- return nullptr;
-
- if (m_pLinearized) {
- CPDF_Dictionary* pDict = m_pLinearized->GetDict();
- CPDF_Object* pObj = pDict ? pDict->GetDirectObjectFor("P") : nullptr;
-
- int pageNum = pObj ? pObj->GetInteger() : 0;
- if (m_pHintTables && index != pageNum) {
- FX_FILESIZE szPageStartPos = 0;
- FX_FILESIZE szPageLength = 0;
- uint32_t dwObjNum = 0;
- bool bPagePosGot = m_pHintTables->GetPagePos(index, &szPageStartPos,
- &szPageLength, &dwObjNum);
- if (!bPagePosGot)
- return nullptr;
-
- m_syntaxParser.InitParser(m_pFileRead, (uint32_t)szPageStartPos);
- CPDF_Object* pPageDict = ParseIndirectObjectAt(0, dwObjNum, m_pDocument);
- if (!pPageDict)
- return nullptr;
-
- if (!m_pDocument->ReplaceIndirectObjectIfHigherGeneration(dwObjNum,
- pPageDict)) {
- return nullptr;
- }
- return pPageDict->GetDict();
- }
- }
- return m_pDocument->GetPage(index);
-}
-
-CPDF_DataAvail::DocFormStatus CPDF_DataAvail::IsFormAvail(
- DownloadHints* pHints) {
- if (!m_pDocument)
- return FormAvailable;
-
- if (!m_bLinearizedFormParamLoad) {
- CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
- if (!pRoot)
- return FormAvailable;
-
- CPDF_Object* pAcroForm = pRoot->GetObjectFor("AcroForm");
- if (!pAcroForm)
- return FormNotExist;
-
- DocAvailStatus nDocStatus = CheckLinearizedData(pHints);
- if (nDocStatus == DataError)
- return FormError;
- if (nDocStatus == DataNotAvailable)
- return FormNotAvailable;
-
- if (!m_objs_array.GetSize())
- m_objs_array.Add(pAcroForm->GetDict());
- m_bLinearizedFormParamLoad = TRUE;
- }
-
- CFX_ArrayTemplate<CPDF_Object*> new_objs_array;
- FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
- m_objs_array.RemoveAll();
- if (!bRet) {
- m_objs_array.Append(new_objs_array);
- return FormNotAvailable;
- }
- return FormAvailable;
-}
-
-CPDF_DataAvail::PageNode::PageNode() : m_type(PDF_PAGENODE_UNKNOWN) {}
-
-CPDF_DataAvail::PageNode::~PageNode() {
- for (int32_t i = 0; i < m_childNode.GetSize(); ++i)
- delete m_childNode[i];
- m_childNode.RemoveAll();
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_data_avail.h b/core/fpdfapi/fpdf_parser/cpdf_data_avail.h
deleted file mode 100644
index 4f8f45b4ed..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_data_avail.h
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_DATA_AVAIL_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_DATA_AVAIL_H_
-
-#include "core/fpdfapi/fpdf_parser/cpdf_parser.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h"
-#include "core/fxcrt/fx_basic.h"
-
-class CPDF_Dictionary;
-class CPDF_HintTables;
-class CPDF_IndirectObjectHolder;
-class CPDF_Parser;
-
-enum PDF_DATAAVAIL_STATUS {
- PDF_DATAAVAIL_HEADER = 0,
- PDF_DATAAVAIL_FIRSTPAGE,
- PDF_DATAAVAIL_FIRSTPAGE_PREPARE,
- PDF_DATAAVAIL_HINTTABLE,
- PDF_DATAAVAIL_END,
- PDF_DATAAVAIL_CROSSREF,
- PDF_DATAAVAIL_CROSSREF_ITEM,
- PDF_DATAAVAIL_CROSSREF_STREAM,
- PDF_DATAAVAIL_TRAILER,
- PDF_DATAAVAIL_LOADALLCROSSREF,
- PDF_DATAAVAIL_ROOT,
- PDF_DATAAVAIL_INFO,
- PDF_DATAAVAIL_ACROFORM,
- PDF_DATAAVAIL_ACROFORM_SUBOBJECT,
- PDF_DATAAVAIL_PAGETREE,
- PDF_DATAAVAIL_PAGE,
- PDF_DATAAVAIL_PAGE_LATERLOAD,
- PDF_DATAAVAIL_RESOURCES,
- PDF_DATAAVAIL_DONE,
- PDF_DATAAVAIL_ERROR,
- PDF_DATAAVAIL_LOADALLFILE,
- PDF_DATAAVAIL_TRAILER_APPEND
-};
-
-enum PDF_PAGENODE_TYPE {
- PDF_PAGENODE_UNKNOWN = 0,
- PDF_PAGENODE_PAGE,
- PDF_PAGENODE_PAGES,
- PDF_PAGENODE_ARRAY,
-};
-
-class CPDF_DataAvail final {
- public:
- // Must match PDF_DATA_* definitions in public/fpdf_dataavail.h, but cannot
- // #include that header. fpdfsdk/fpdf_dataavail.cpp has static_asserts
- // to make sure the two sets of values match.
- enum DocAvailStatus {
- DataError = -1, // PDF_DATA_ERROR
- DataNotAvailable = 0, // PDF_DATA_NOTAVAIL
- DataAvailable = 1, // PDF_DATA_AVAIL
- };
-
- // Must match PDF_*LINEAR* definitions in public/fpdf_dataavail.h, but cannot
- // #include that header. fpdfsdk/fpdf_dataavail.cpp has static_asserts
- // to make sure the two sets of values match.
- enum DocLinearizationStatus {
- LinearizationUnknown = -1, // PDF_LINEARIZATION_UNKNOWN
- NotLinearized = 0, // PDF_NOT_LINEARIZED
- Linearized = 1, // PDF_LINEARIZED
- };
-
- // Must match PDF_FORM_* definitions in public/fpdf_dataavail.h, but cannot
- // #include that header. fpdfsdk/fpdf_dataavail.cpp has static_asserts
- // to make sure the two sets of values match.
- enum DocFormStatus {
- FormError = -1, // PDF_FORM_ERROR
- FormNotAvailable = 0, // PDF_FORM_NOTAVAIL
- FormAvailable = 1, // PDF_FORM_AVAIL
- FormNotExist = 2, // PDF_FORM_NOTEXIST
- };
-
- class FileAvail {
- public:
- virtual ~FileAvail();
- virtual FX_BOOL IsDataAvail(FX_FILESIZE offset, uint32_t size) = 0;
- };
-
- class DownloadHints {
- public:
- virtual ~DownloadHints();
- virtual void AddSegment(FX_FILESIZE offset, uint32_t size) = 0;
- };
-
- CPDF_DataAvail(FileAvail* pFileAvail,
- IFX_FileRead* pFileRead,
- FX_BOOL bSupportHintTable);
- ~CPDF_DataAvail();
-
- DocAvailStatus IsDocAvail(DownloadHints* pHints);
- void SetDocument(CPDF_Document* pDoc);
- DocAvailStatus IsPageAvail(uint32_t dwPage, DownloadHints* pHints);
- DocFormStatus IsFormAvail(DownloadHints* pHints);
- DocLinearizationStatus IsLinearizedPDF();
- FX_BOOL IsLinearized();
- void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, uint32_t* pSize);
- IFX_FileRead* GetFileRead() const { return m_pFileRead; }
- int GetPageCount() const;
- CPDF_Dictionary* GetPage(int index);
-
- friend class CPDF_HintTables;
-
- protected:
- class PageNode {
- public:
- PageNode();
- ~PageNode();
-
- PDF_PAGENODE_TYPE m_type;
- uint32_t m_dwPageNo;
- CFX_ArrayTemplate<PageNode*> m_childNode;
- };
-
- static const int kMaxDataAvailRecursionDepth = 64;
- static int s_CurrentDataAvailRecursionDepth;
- static const int kMaxPageRecursionDepth = 1024;
-
- uint32_t GetObjectSize(uint32_t objnum, FX_FILESIZE& offset);
- FX_BOOL IsObjectsAvail(CFX_ArrayTemplate<CPDF_Object*>& obj_array,
- FX_BOOL bParsePage,
- DownloadHints* pHints,
- CFX_ArrayTemplate<CPDF_Object*>& ret_array);
- FX_BOOL CheckDocStatus(DownloadHints* pHints);
- FX_BOOL CheckHeader(DownloadHints* pHints);
- FX_BOOL CheckFirstPage(DownloadHints* pHints);
- FX_BOOL CheckHintTables(DownloadHints* pHints);
- FX_BOOL CheckEnd(DownloadHints* pHints);
- FX_BOOL CheckCrossRef(DownloadHints* pHints);
- FX_BOOL CheckCrossRefItem(DownloadHints* pHints);
- FX_BOOL CheckTrailer(DownloadHints* pHints);
- FX_BOOL CheckRoot(DownloadHints* pHints);
- FX_BOOL CheckInfo(DownloadHints* pHints);
- FX_BOOL CheckPages(DownloadHints* pHints);
- FX_BOOL CheckPage(DownloadHints* pHints);
- FX_BOOL CheckResources(DownloadHints* pHints);
- FX_BOOL CheckAnnots(DownloadHints* pHints);
- FX_BOOL CheckAcroForm(DownloadHints* pHints);
- FX_BOOL CheckAcroFormSubObject(DownloadHints* pHints);
- FX_BOOL CheckTrailerAppend(DownloadHints* pHints);
- FX_BOOL CheckPageStatus(DownloadHints* pHints);
- FX_BOOL CheckAllCrossRefStream(DownloadHints* pHints);
-
- int32_t CheckCrossRefStream(DownloadHints* pHints, FX_FILESIZE& xref_offset);
- FX_BOOL IsLinearizedFile(uint8_t* pData, uint32_t dwLen);
- void SetStartOffset(FX_FILESIZE dwOffset);
- FX_BOOL GetNextToken(CFX_ByteString& token);
- FX_BOOL GetNextChar(uint8_t& ch);
- CPDF_Object* ParseIndirectObjectAt(
- FX_FILESIZE pos,
- uint32_t objnum,
- CPDF_IndirectObjectHolder* pObjList = nullptr);
- CPDF_Object* GetObject(uint32_t objnum,
- DownloadHints* pHints,
- FX_BOOL* pExistInFile);
- FX_BOOL GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages);
- FX_BOOL PreparePageItem();
- FX_BOOL LoadPages(DownloadHints* pHints);
- FX_BOOL LoadAllXref(DownloadHints* pHints);
- FX_BOOL LoadAllFile(DownloadHints* pHints);
- DocAvailStatus CheckLinearizedData(DownloadHints* pHints);
- FX_BOOL CheckPageAnnots(uint32_t dwPage, DownloadHints* pHints);
-
- DocAvailStatus CheckLinearizedFirstPage(uint32_t dwPage,
- DownloadHints* pHints);
- FX_BOOL HaveResourceAncestor(CPDF_Dictionary* pDict);
- FX_BOOL CheckPage(uint32_t dwPage, DownloadHints* pHints);
- FX_BOOL LoadDocPages(DownloadHints* pHints);
- FX_BOOL LoadDocPage(uint32_t dwPage, DownloadHints* pHints);
- FX_BOOL CheckPageNode(PageNode& pageNodes,
- int32_t iPage,
- int32_t& iCount,
- DownloadHints* pHints,
- int level);
- FX_BOOL CheckUnkownPageNode(uint32_t dwPageNo,
- PageNode* pPageNode,
- DownloadHints* pHints);
- FX_BOOL CheckArrayPageNode(uint32_t dwPageNo,
- PageNode* pPageNode,
- DownloadHints* pHints);
- FX_BOOL CheckPageCount(DownloadHints* pHints);
- bool IsFirstCheck(uint32_t dwPage);
- void ResetFirstCheck(uint32_t dwPage);
- FX_BOOL IsDataAvail(FX_FILESIZE offset, uint32_t size, DownloadHints* pHints);
-
- FileAvail* const m_pFileAvail;
- IFX_FileRead* const m_pFileRead;
- CPDF_Parser m_parser;
- CPDF_SyntaxParser m_syntaxParser;
- CPDF_Object* m_pRoot;
- uint32_t m_dwRootObjNum;
- uint32_t m_dwInfoObjNum;
- CPDF_Object* m_pLinearized;
- CPDF_Object* m_pTrailer;
- FX_BOOL m_bDocAvail;
- FX_FILESIZE m_dwHeaderOffset;
- FX_FILESIZE m_dwLastXRefOffset;
- FX_FILESIZE m_dwXRefOffset;
- FX_FILESIZE m_dwTrailerOffset;
- FX_FILESIZE m_dwCurrentOffset;
- PDF_DATAAVAIL_STATUS m_docStatus;
- FX_FILESIZE m_dwFileLen;
- CPDF_Document* m_pDocument;
- std::set<uint32_t> m_ObjectSet;
- CFX_ArrayTemplate<CPDF_Object*> m_objs_array;
- FX_FILESIZE m_Pos;
- FX_FILESIZE m_bufferOffset;
- uint32_t m_bufferSize;
- CFX_ByteString m_WordBuf;
- uint8_t m_bufferData[512];
- CFX_ArrayTemplate<uint32_t> m_XRefStreamList;
- CFX_ArrayTemplate<uint32_t> m_PageObjList;
- uint32_t m_PagesObjNum;
- FX_BOOL m_bLinearized;
- uint32_t m_dwFirstPageNo;
- FX_BOOL m_bLinearedDataOK;
- FX_BOOL m_bMainXRefLoadTried;
- FX_BOOL m_bMainXRefLoadedOK;
- FX_BOOL m_bPagesTreeLoad;
- FX_BOOL m_bPagesLoad;
- CPDF_Parser* m_pCurrentParser;
- FX_FILESIZE m_dwCurrentXRefSteam;
- FX_BOOL m_bAnnotsLoad;
- FX_BOOL m_bHaveAcroForm;
- uint32_t m_dwAcroFormObjNum;
- FX_BOOL m_bAcroFormLoad;
- CPDF_Object* m_pAcroForm;
- CFX_ArrayTemplate<CPDF_Object*> m_arrayAcroforms;
- CPDF_Dictionary* m_pPageDict;
- CPDF_Object* m_pPageResource;
- FX_BOOL m_bNeedDownLoadResource;
- FX_BOOL m_bPageLoadedOK;
- FX_BOOL m_bLinearizedFormParamLoad;
- CFX_ArrayTemplate<CPDF_Object*> m_PagesArray;
- uint32_t m_dwEncryptObjNum;
- FX_FILESIZE m_dwPrevXRefOffset;
- FX_BOOL m_bTotalLoadPageTree;
- FX_BOOL m_bCurPageDictLoadOK;
- PageNode m_pageNodes;
- std::set<uint32_t> m_pageMapCheckState;
- std::set<uint32_t> m_pagesLoadState;
- std::unique_ptr<CPDF_HintTables> m_pHintTables;
- FX_BOOL m_bSupportHintTable;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_DATA_AVAIL_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_dictionary.cpp b/core/fpdfapi/fpdf_parser/cpdf_dictionary.cpp
deleted file mode 100644
index 5696fc0c8d..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_dictionary.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-
-#include <set>
-#include <utility>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_boolean.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_name.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_number.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_string.h"
-#include "third_party/base/logging.h"
-#include "third_party/base/stl_util.h"
-
-CPDF_Dictionary::CPDF_Dictionary()
- : CPDF_Dictionary(CFX_WeakPtr<CFX_ByteStringPool>()) {}
-
-CPDF_Dictionary::CPDF_Dictionary(const CFX_WeakPtr<CFX_ByteStringPool>& pPool)
- : m_pPool(pPool) {}
-
-CPDF_Dictionary::~CPDF_Dictionary() {
- // Mark the object as deleted so that it will not be deleted again
- // in case of cyclic references.
- m_ObjNum = kInvalidObjNum;
- for (const auto& it : m_Map) {
- if (it.second)
- it.second->Release();
- }
-}
-
-CPDF_Object::Type CPDF_Dictionary::GetType() const {
- return DICTIONARY;
-}
-
-CPDF_Dictionary* CPDF_Dictionary::GetDict() const {
- // The method should be made non-const if we want to not be const.
- // See bug #234.
- return const_cast<CPDF_Dictionary*>(this);
-}
-
-bool CPDF_Dictionary::IsDictionary() const {
- return true;
-}
-
-CPDF_Dictionary* CPDF_Dictionary::AsDictionary() {
- return this;
-}
-
-const CPDF_Dictionary* CPDF_Dictionary::AsDictionary() const {
- return this;
-}
-
-CPDF_Object* CPDF_Dictionary::Clone() const {
- return CloneObjectNonCyclic(false);
-}
-
-CPDF_Object* CPDF_Dictionary::CloneNonCyclic(
- bool bDirect,
- std::set<const CPDF_Object*>* pVisited) const {
- pVisited->insert(this);
- CPDF_Dictionary* pCopy = new CPDF_Dictionary(m_pPool);
- for (const auto& it : *this) {
- CPDF_Object* value = it.second;
- if (!pdfium::ContainsKey(*pVisited, value)) {
- pCopy->m_Map.insert(
- std::make_pair(it.first, value->CloneNonCyclic(bDirect, pVisited)));
- }
- }
- return pCopy;
-}
-
-CPDF_Object* CPDF_Dictionary::GetObjectFor(const CFX_ByteString& key) const {
- auto it = m_Map.find(key);
- return it != m_Map.end() ? it->second : nullptr;
-}
-
-CPDF_Object* CPDF_Dictionary::GetDirectObjectFor(
- const CFX_ByteString& key) const {
- CPDF_Object* p = GetObjectFor(key);
- return p ? p->GetDirect() : nullptr;
-}
-
-CFX_ByteString CPDF_Dictionary::GetStringFor(const CFX_ByteString& key) const {
- CPDF_Object* p = GetObjectFor(key);
- return p ? p->GetString() : CFX_ByteString();
-}
-
-CFX_WideString CPDF_Dictionary::GetUnicodeTextFor(
- const CFX_ByteString& key) const {
- CPDF_Object* p = GetObjectFor(key);
- if (CPDF_Reference* pRef = ToReference(p))
- p = pRef->GetDirect();
- return p ? p->GetUnicodeText() : CFX_WideString();
-}
-
-CFX_ByteString CPDF_Dictionary::GetStringFor(const CFX_ByteString& key,
- const CFX_ByteString& def) const {
- CPDF_Object* p = GetObjectFor(key);
- return p ? p->GetString() : CFX_ByteString(def);
-}
-
-int CPDF_Dictionary::GetIntegerFor(const CFX_ByteString& key) const {
- CPDF_Object* p = GetObjectFor(key);
- return p ? p->GetInteger() : 0;
-}
-
-int CPDF_Dictionary::GetIntegerFor(const CFX_ByteString& key, int def) const {
- CPDF_Object* p = GetObjectFor(key);
- return p ? p->GetInteger() : def;
-}
-
-FX_FLOAT CPDF_Dictionary::GetNumberFor(const CFX_ByteString& key) const {
- CPDF_Object* p = GetObjectFor(key);
- return p ? p->GetNumber() : 0;
-}
-
-bool CPDF_Dictionary::GetBooleanFor(const CFX_ByteString& key,
- bool bDefault) const {
- CPDF_Object* p = GetObjectFor(key);
- return ToBoolean(p) ? p->GetInteger() != 0 : bDefault;
-}
-
-CPDF_Dictionary* CPDF_Dictionary::GetDictFor(const CFX_ByteString& key) const {
- CPDF_Object* p = GetDirectObjectFor(key);
- if (!p)
- return nullptr;
- if (CPDF_Dictionary* pDict = p->AsDictionary())
- return pDict;
- if (CPDF_Stream* pStream = p->AsStream())
- return pStream->GetDict();
- return nullptr;
-}
-
-CPDF_Array* CPDF_Dictionary::GetArrayFor(const CFX_ByteString& key) const {
- return ToArray(GetDirectObjectFor(key));
-}
-
-CPDF_Stream* CPDF_Dictionary::GetStreamFor(const CFX_ByteString& key) const {
- return ToStream(GetDirectObjectFor(key));
-}
-
-CFX_FloatRect CPDF_Dictionary::GetRectFor(const CFX_ByteString& key) const {
- CFX_FloatRect rect;
- CPDF_Array* pArray = GetArrayFor(key);
- if (pArray)
- rect = pArray->GetRect();
- return rect;
-}
-
-CFX_Matrix CPDF_Dictionary::GetMatrixFor(const CFX_ByteString& key) const {
- CFX_Matrix matrix;
- CPDF_Array* pArray = GetArrayFor(key);
- if (pArray)
- matrix = pArray->GetMatrix();
- return matrix;
-}
-
-FX_BOOL CPDF_Dictionary::KeyExist(const CFX_ByteString& key) const {
- return pdfium::ContainsKey(m_Map, key);
-}
-
-bool CPDF_Dictionary::IsSignatureDict() const {
- CPDF_Object* pType = GetDirectObjectFor("Type");
- if (!pType)
- pType = GetDirectObjectFor("FT");
- return pType && pType->GetString() == "Sig";
-}
-
-void CPDF_Dictionary::SetFor(const CFX_ByteString& key, CPDF_Object* pObj) {
- CHECK(!pObj || pObj->GetObjNum() == 0);
- auto it = m_Map.find(key);
- if (it == m_Map.end()) {
- if (pObj)
- m_Map.insert(std::make_pair(MaybeIntern(key), pObj));
- return;
- }
-
- if (it->second == pObj)
- return;
- it->second->Release();
-
- if (pObj)
- it->second = pObj;
- else
- m_Map.erase(it);
-}
-
-void CPDF_Dictionary::RemoveFor(const CFX_ByteString& key) {
- auto it = m_Map.find(key);
- if (it == m_Map.end())
- return;
-
- it->second->Release();
- m_Map.erase(it);
-}
-
-void CPDF_Dictionary::ReplaceKey(const CFX_ByteString& oldkey,
- const CFX_ByteString& newkey) {
- auto old_it = m_Map.find(oldkey);
- if (old_it == m_Map.end())
- return;
-
- auto new_it = m_Map.find(newkey);
- if (new_it == old_it)
- return;
-
- if (new_it != m_Map.end()) {
- new_it->second->Release();
- new_it->second = old_it->second;
- } else {
- m_Map.insert(std::make_pair(MaybeIntern(newkey), old_it->second));
- }
- m_Map.erase(old_it);
-}
-
-void CPDF_Dictionary::SetIntegerFor(const CFX_ByteString& key, int i) {
- SetFor(key, new CPDF_Number(i));
-}
-
-void CPDF_Dictionary::SetNameFor(const CFX_ByteString& key,
- const CFX_ByteString& name) {
- SetFor(key, new CPDF_Name(MaybeIntern(name)));
-}
-
-void CPDF_Dictionary::SetStringFor(const CFX_ByteString& key,
- const CFX_ByteString& str) {
- SetFor(key, new CPDF_String(MaybeIntern(str), FALSE));
-}
-
-void CPDF_Dictionary::SetReferenceFor(const CFX_ByteString& key,
- CPDF_IndirectObjectHolder* pDoc,
- uint32_t objnum) {
- SetFor(key, new CPDF_Reference(pDoc, objnum));
-}
-
-void CPDF_Dictionary::SetNumberFor(const CFX_ByteString& key, FX_FLOAT f) {
- SetFor(key, new CPDF_Number(f));
-}
-
-void CPDF_Dictionary::SetBooleanFor(const CFX_ByteString& key, bool bValue) {
- SetFor(key, new CPDF_Boolean(bValue));
-}
-
-void CPDF_Dictionary::SetRectFor(const CFX_ByteString& key,
- const CFX_FloatRect& rect) {
- CPDF_Array* pArray = new CPDF_Array;
- pArray->AddNumber(rect.left);
- pArray->AddNumber(rect.bottom);
- pArray->AddNumber(rect.right);
- pArray->AddNumber(rect.top);
- SetFor(key, pArray);
-}
-
-void CPDF_Dictionary::SetMatrixFor(const CFX_ByteString& key,
- const CFX_Matrix& matrix) {
- CPDF_Array* pArray = new CPDF_Array;
- pArray->AddNumber(matrix.a);
- pArray->AddNumber(matrix.b);
- pArray->AddNumber(matrix.c);
- pArray->AddNumber(matrix.d);
- pArray->AddNumber(matrix.e);
- pArray->AddNumber(matrix.f);
- SetFor(key, pArray);
-}
-
-CFX_ByteString CPDF_Dictionary::MaybeIntern(const CFX_ByteString& str) {
- return m_pPool ? m_pPool->Intern(str) : str;
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_dictionary.h b/core/fpdfapi/fpdf_parser/cpdf_dictionary.h
deleted file mode 100644
index e3fd594575..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_dictionary.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_DICTIONARY_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_DICTIONARY_H_
-
-#include <map>
-#include <set>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-#include "core/fxcrt/cfx_string_pool_template.h"
-#include "core/fxcrt/cfx_weak_ptr.h"
-#include "core/fxcrt/fx_coordinates.h"
-#include "core/fxcrt/fx_string.h"
-
-class CPDF_IndirectObjectHolder;
-
-class CPDF_Dictionary : public CPDF_Object {
- public:
- using iterator = std::map<CFX_ByteString, CPDF_Object*>::iterator;
- using const_iterator = std::map<CFX_ByteString, CPDF_Object*>::const_iterator;
-
- CPDF_Dictionary();
- explicit CPDF_Dictionary(const CFX_WeakPtr<CFX_ByteStringPool>& pPool);
-
- // CPDF_Object.
- Type GetType() const override;
- CPDF_Object* Clone() const override;
- CPDF_Dictionary* GetDict() const override;
- bool IsDictionary() const override;
- CPDF_Dictionary* AsDictionary() override;
- const CPDF_Dictionary* AsDictionary() const override;
-
- size_t GetCount() const { return m_Map.size(); }
- CPDF_Object* GetObjectFor(const CFX_ByteString& key) const;
- CPDF_Object* GetDirectObjectFor(const CFX_ByteString& key) const;
- CFX_ByteString GetStringFor(const CFX_ByteString& key) const;
- CFX_ByteString GetStringFor(const CFX_ByteString& key,
- const CFX_ByteString& default_str) const;
- CFX_WideString GetUnicodeTextFor(const CFX_ByteString& key) const;
- int GetIntegerFor(const CFX_ByteString& key) const;
- int GetIntegerFor(const CFX_ByteString& key, int default_int) const;
- bool GetBooleanFor(const CFX_ByteString& key, bool bDefault = false) const;
- FX_FLOAT GetNumberFor(const CFX_ByteString& key) const;
- CPDF_Dictionary* GetDictFor(const CFX_ByteString& key) const;
- CPDF_Stream* GetStreamFor(const CFX_ByteString& key) const;
- CPDF_Array* GetArrayFor(const CFX_ByteString& key) const;
- CFX_FloatRect GetRectFor(const CFX_ByteString& key) const;
- CFX_Matrix GetMatrixFor(const CFX_ByteString& key) const;
- FX_FLOAT GetFloatFor(const CFX_ByteString& key) const {
- return GetNumberFor(key);
- }
-
- FX_BOOL KeyExist(const CFX_ByteString& key) const;
- bool IsSignatureDict() const;
-
- // Set* functions invalidate iterators for the element with the key |key|.
- void SetFor(const CFX_ByteString& key, CPDF_Object* pObj);
- void SetNameFor(const CFX_ByteString& key, const CFX_ByteString& name);
- void SetStringFor(const CFX_ByteString& key, const CFX_ByteString& str);
- void SetIntegerFor(const CFX_ByteString& key, int i);
- void SetNumberFor(const CFX_ByteString& key, FX_FLOAT f);
- void SetReferenceFor(const CFX_ByteString& key,
- CPDF_IndirectObjectHolder* pDoc,
- uint32_t objnum);
- void SetRectFor(const CFX_ByteString& key, const CFX_FloatRect& rect);
- void SetMatrixFor(const CFX_ByteString& key, const CFX_Matrix& matrix);
- void SetBooleanFor(const CFX_ByteString& key, bool bValue);
-
- // Invalidates iterators for the element with the key |key|.
- void RemoveFor(const CFX_ByteString& key);
-
- // Invalidates iterators for the element with the key |oldkey|.
- void ReplaceKey(const CFX_ByteString& oldkey, const CFX_ByteString& newkey);
-
- iterator begin() { return m_Map.begin(); }
- iterator end() { return m_Map.end(); }
- const_iterator begin() const { return m_Map.begin(); }
- const_iterator end() const { return m_Map.end(); }
-
- CFX_WeakPtr<CFX_ByteStringPool> GetByteStringPool() const { return m_pPool; }
-
- protected:
- ~CPDF_Dictionary() override;
-
- CFX_ByteString MaybeIntern(const CFX_ByteString& str);
- CPDF_Object* CloneNonCyclic(
- bool bDirect,
- std::set<const CPDF_Object*>* visited) const override;
-
- CFX_WeakPtr<CFX_ByteStringPool> m_pPool;
- std::map<CFX_ByteString, CPDF_Object*> m_Map;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_DICTIONARY_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_document.cpp b/core/fpdfapi/fpdf_parser/cpdf_document.cpp
deleted file mode 100644
index 21469af179..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_document.cpp
+++ /dev/null
@@ -1,1020 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_document.h"
-
-#include <memory>
-#include <set>
-#include <vector>
-
-#include "core/fpdfapi/cpdf_modulemgr.h"
-#include "core/fpdfapi/font/cpdf_fontencoding.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_parser.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
-#include "core/fpdfapi/fpdf_render/render_int.h"
-#include "core/fpdfapi/page/cpdf_pagemodule.h"
-#include "core/fpdfapi/page/pageint.h"
-#include "core/fxcodec/JBig2_DocumentContext.h"
-#include "core/fxge/cfx_unicodeencoding.h"
-#include "core/fxge/fx_font.h"
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
-
-namespace {
-
-const int FX_MAX_PAGE_LEVEL = 1024;
-
-const uint16_t g_FX_CP874Unicodes[128] = {
- 0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
- 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x0E01, 0x0E02, 0x0E03,
- 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C,
- 0x0E0D, 0x0E0E, 0x0E0F, 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15,
- 0x0E16, 0x0E17, 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E,
- 0x0E1F, 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
- 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, 0x0E30,
- 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, 0x0E38, 0x0E39,
- 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F, 0x0E40, 0x0E41, 0x0E42,
- 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, 0x0E48, 0x0E49, 0x0E4A, 0x0E4B,
- 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54,
- 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000,
- 0x0000, 0x0000,
-};
-const uint16_t g_FX_CP1250Unicodes[128] = {
- 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
- 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, 0x0000, 0x2018,
- 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161,
- 0x203A, 0x015B, 0x0165, 0x017E, 0x017A, 0x00A0, 0x02C7, 0x02D8, 0x0141,
- 0x00A4, 0x0104, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC,
- 0x00AD, 0x00AE, 0x017B, 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5,
- 0x00B6, 0x00B7, 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E,
- 0x017C, 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
- 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, 0x0110,
- 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E,
- 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, 0x0155, 0x00E1, 0x00E2,
- 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB,
- 0x011B, 0x00ED, 0x00EE, 0x010F, 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4,
- 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD,
- 0x0163, 0x02D9,
-};
-const uint16_t g_FX_CP1251Unicodes[128] = {
- 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC,
- 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, 0x0452, 0x2018,
- 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459,
- 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, 0x00A0, 0x040E, 0x045E, 0x0408,
- 0x00A4, 0x0490, 0x00A6, 0x00A7, 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC,
- 0x00AD, 0x00AE, 0x0407, 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5,
- 0x00B6, 0x00B7, 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455,
- 0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
- 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
- 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429,
- 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432,
- 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B,
- 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444,
- 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D,
- 0x044E, 0x044F,
-};
-const uint16_t g_FX_CP1253Unicodes[128] = {
- 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
- 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
- 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000,
- 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x0385, 0x0386, 0x00A3,
- 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC,
- 0x00AD, 0x00AE, 0x2015, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5,
- 0x00B6, 0x00B7, 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E,
- 0x038F, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
- 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
- 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
- 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03B0, 0x03B1, 0x03B2,
- 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB,
- 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4,
- 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD,
- 0x03CE, 0x0000,
-};
-const uint16_t g_FX_CP1254Unicodes[128] = {
- 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
- 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
- 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161,
- 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, 0x00A0, 0x00A1, 0x00A2, 0x00A3,
- 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC,
- 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
- 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
- 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
- 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x011E,
- 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9,
- 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, 0x00E0, 0x00E1, 0x00E2,
- 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB,
- 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4,
- 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131,
- 0x015F, 0x00FF,
-};
-const uint16_t g_FX_CP1255Unicodes[128] = {
- 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
- 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
- 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0000,
- 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x00A1, 0x00A2, 0x00A3,
- 0x20AA, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC,
- 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
- 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
- 0x00BF, 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
- 0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, 0x05C0,
- 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x05D0, 0x05D1, 0x05D2,
- 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB,
- 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4,
- 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E,
- 0x200F, 0x0000,
-};
-const uint16_t g_FX_CP1256Unicodes[128] = {
- 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
- 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, 0x06AF, 0x2018,
- 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x06A9, 0x2122, 0x0691,
- 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, 0x00A0, 0x060C, 0x00A2, 0x00A3,
- 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC,
- 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
- 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
- 0x061F, 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
- 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630,
- 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, 0x0637, 0x0638,
- 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643, 0x00E0, 0x0644, 0x00E2,
- 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB,
- 0x0649, 0x064A, 0x00EE, 0x00EF, 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4,
- 0x064F, 0x0650, 0x00F7, 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E,
- 0x200F, 0x06D2,
-};
-const uint16_t g_FX_CP1257Unicodes[128] = {
- 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
- 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8, 0x0000, 0x2018,
- 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000,
- 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000, 0x00A0, 0x0000, 0x00A2, 0x00A3,
- 0x00A4, 0x0000, 0x00A6, 0x00A7, 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC,
- 0x00AD, 0x00AE, 0x00C6, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
- 0x00B6, 0x00B7, 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
- 0x00E6, 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
- 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, 0x0160,
- 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, 0x0172, 0x0141,
- 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, 0x0105, 0x012F, 0x0101,
- 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, 0x010D, 0x00E9, 0x017A, 0x0117,
- 0x0123, 0x0137, 0x012B, 0x013C, 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D,
- 0x00F5, 0x00F6, 0x00F7, 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C,
- 0x017E, 0x02D9,
-};
-
-struct FX_CharsetUnicodes {
- uint8_t m_Charset;
- const uint16_t* m_pUnicodes;
-};
-
-const FX_CharsetUnicodes g_FX_CharsetUnicodes[] = {
- {FXFONT_THAI_CHARSET, g_FX_CP874Unicodes},
- {FXFONT_EASTEUROPE_CHARSET, g_FX_CP1250Unicodes},
- {FXFONT_RUSSIAN_CHARSET, g_FX_CP1251Unicodes},
- {FXFONT_GREEK_CHARSET, g_FX_CP1253Unicodes},
- {FXFONT_TURKISH_CHARSET, g_FX_CP1254Unicodes},
- {FXFONT_HEBREW_CHARSET, g_FX_CP1255Unicodes},
- {FXFONT_ARABIC_CHARSET, g_FX_CP1256Unicodes},
- {FXFONT_BALTIC_CHARSET, g_FX_CP1257Unicodes},
-};
-
-void InsertWidthArrayImpl(int* widths, int size, CPDF_Array* pWidthArray) {
- int i;
- for (i = 1; i < size; i++) {
- if (widths[i] != *widths)
- break;
- }
- if (i == size) {
- int first = pWidthArray->GetIntegerAt(pWidthArray->GetCount() - 1);
- pWidthArray->AddInteger(first + size - 1);
- pWidthArray->AddInteger(*widths);
- } else {
- CPDF_Array* pWidthArray1 = new CPDF_Array;
- pWidthArray->Add(pWidthArray1);
- for (i = 0; i < size; i++)
- pWidthArray1->AddInteger(widths[i]);
- }
- FX_Free(widths);
-}
-
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
-void InsertWidthArray(HDC hDC, int start, int end, CPDF_Array* pWidthArray) {
- int size = end - start + 1;
- int* widths = FX_Alloc(int, size);
- GetCharWidth(hDC, start, end, widths);
- InsertWidthArrayImpl(widths, size, pWidthArray);
-}
-
-CFX_ByteString FPDF_GetPSNameFromTT(HDC hDC) {
- CFX_ByteString result;
- DWORD size = ::GetFontData(hDC, 'eman', 0, nullptr, 0);
- if (size != GDI_ERROR) {
- LPBYTE buffer = FX_Alloc(BYTE, size);
- ::GetFontData(hDC, 'eman', 0, buffer, size);
- result = GetNameFromTT(buffer, size, 6);
- FX_Free(buffer);
- }
- return result;
-}
-#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
-
-void InsertWidthArray1(CFX_Font* pFont,
- CFX_UnicodeEncoding* pEncoding,
- FX_WCHAR start,
- FX_WCHAR end,
- CPDF_Array* pWidthArray) {
- int size = end - start + 1;
- int* widths = FX_Alloc(int, size);
- int i;
- for (i = 0; i < size; i++) {
- int glyph_index = pEncoding->GlyphFromCharCode(start + i);
- widths[i] = pFont->GetGlyphWidth(glyph_index);
- }
- InsertWidthArrayImpl(widths, size, pWidthArray);
-}
-
-int InsertDeletePDFPage(CPDF_Document* pDoc,
- CPDF_Dictionary* pPages,
- int nPagesToGo,
- CPDF_Dictionary* pPage,
- FX_BOOL bInsert,
- std::set<CPDF_Dictionary*>* pVisited) {
- CPDF_Array* pKidList = pPages->GetArrayFor("Kids");
- if (!pKidList)
- return -1;
-
- for (size_t i = 0; i < pKidList->GetCount(); i++) {
- CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
- if (pKid->GetStringFor("Type") == "Page") {
- if (nPagesToGo == 0) {
- if (bInsert) {
- pKidList->InsertAt(i, new CPDF_Reference(pDoc, pPage->GetObjNum()));
- pPage->SetReferenceFor("Parent", pDoc, pPages->GetObjNum());
- } else {
- pKidList->RemoveAt(i);
- }
- pPages->SetIntegerFor(
- "Count", pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1));
- return 1;
- }
- nPagesToGo--;
- } else {
- int nPages = pKid->GetIntegerFor("Count");
- if (nPagesToGo < nPages) {
- if (pdfium::ContainsKey(*pVisited, pKid))
- return -1;
-
- pdfium::ScopedSetInsertion<CPDF_Dictionary*> insertion(pVisited, pKid);
- if (InsertDeletePDFPage(pDoc, pKid, nPagesToGo, pPage, bInsert,
- pVisited) < 0) {
- return -1;
- }
- pPages->SetIntegerFor(
- "Count", pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1));
- return 1;
- }
- nPagesToGo -= nPages;
- }
- }
- return 0;
-}
-
-int InsertNewPage(CPDF_Document* pDoc,
- int iPage,
- CPDF_Dictionary* pPageDict,
- CFX_ArrayTemplate<uint32_t>& pageList) {
- CPDF_Dictionary* pRoot = pDoc->GetRoot();
- CPDF_Dictionary* pPages = pRoot ? pRoot->GetDictFor("Pages") : nullptr;
- if (!pPages)
- return -1;
-
- int nPages = pDoc->GetPageCount();
- if (iPage < 0 || iPage > nPages)
- return -1;
-
- if (iPage == nPages) {
- CPDF_Array* pPagesList = pPages->GetArrayFor("Kids");
- if (!pPagesList) {
- pPagesList = new CPDF_Array;
- pPages->SetFor("Kids", pPagesList);
- }
- pPagesList->Add(new CPDF_Reference(pDoc, pPageDict->GetObjNum()));
- pPages->SetIntegerFor("Count", nPages + 1);
- pPageDict->SetReferenceFor("Parent", pDoc, pPages->GetObjNum());
- } else {
- std::set<CPDF_Dictionary*> stack = {pPages};
- if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, &stack) < 0)
- return -1;
- }
- pageList.InsertAt(iPage, pPageDict->GetObjNum());
- return iPage;
-}
-
-int CountPages(CPDF_Dictionary* pPages,
- std::set<CPDF_Dictionary*>* visited_pages) {
- int count = pPages->GetIntegerFor("Count");
- if (count > 0 && count < FPDF_PAGE_MAX_NUM)
- return count;
- CPDF_Array* pKidList = pPages->GetArrayFor("Kids");
- if (!pKidList)
- return 0;
- count = 0;
- for (size_t i = 0; i < pKidList->GetCount(); i++) {
- CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
- if (!pKid || pdfium::ContainsKey(*visited_pages, pKid))
- continue;
- if (pKid->KeyExist("Kids")) {
- // Use |visited_pages| to help detect circular references of pages.
- pdfium::ScopedSetInsertion<CPDF_Dictionary*> local_add(visited_pages,
- pKid);
- count += CountPages(pKid, visited_pages);
- } else {
- // This page is a leaf node.
- count++;
- }
- }
- pPages->SetIntegerFor("Count", count);
- return count;
-}
-
-int CalculateFlags(bool bold,
- bool italic,
- bool fixedPitch,
- bool serif,
- bool script,
- bool symbolic) {
- int flags = 0;
- if (bold)
- flags |= PDFFONT_FORCEBOLD;
- if (italic)
- flags |= PDFFONT_ITALIC;
- if (fixedPitch)
- flags |= PDFFONT_FIXEDPITCH;
- if (serif)
- flags |= PDFFONT_SERIF;
- if (script)
- flags |= PDFFONT_SCRIPT;
- if (symbolic)
- flags |= PDFFONT_SYMBOLIC;
- else
- flags |= PDFFONT_NONSYMBOLIC;
- return flags;
-}
-
-void ProcessNonbCJK(CPDF_Dictionary* pBaseDict,
- bool bold,
- bool italic,
- CFX_ByteString basefont,
- CPDF_Array* pWidths) {
- if (bold && italic)
- basefont += ",BoldItalic";
- else if (bold)
- basefont += ",Bold";
- else if (italic)
- basefont += ",Italic";
- pBaseDict->SetNameFor("Subtype", "TrueType");
- pBaseDict->SetNameFor("BaseFont", basefont);
- pBaseDict->SetNumberFor("FirstChar", 32);
- pBaseDict->SetNumberFor("LastChar", 255);
- pBaseDict->SetFor("Widths", pWidths);
-}
-
-CPDF_Dictionary* CalculateFontDesc(CPDF_Document* pDoc,
- CFX_ByteString basefont,
- int flags,
- int italicangle,
- int ascend,
- int descend,
- CPDF_Array* bbox,
- int32_t stemV) {
- CPDF_Dictionary* pFontDesc = new CPDF_Dictionary(pDoc->GetByteStringPool());
- pFontDesc->SetNameFor("Type", "FontDescriptor");
- pFontDesc->SetNameFor("FontName", basefont);
- pFontDesc->SetIntegerFor("Flags", flags);
- pFontDesc->SetFor("FontBBox", bbox);
- pFontDesc->SetIntegerFor("ItalicAngle", italicangle);
- pFontDesc->SetIntegerFor("Ascent", ascend);
- pFontDesc->SetIntegerFor("Descent", descend);
- pFontDesc->SetIntegerFor("StemV", stemV);
- return pFontDesc;
-}
-
-} // namespace
-
-CPDF_Document::CPDF_Document(std::unique_ptr<CPDF_Parser> pParser)
- : CPDF_IndirectObjectHolder(),
- m_pParser(std::move(pParser)),
- m_pRootDict(nullptr),
- m_pInfoDict(nullptr),
- m_bLinearized(false),
- m_iFirstPageNo(0),
- m_dwFirstPageObjNum(0),
- m_pDocPage(new CPDF_DocPageData(this)),
- m_pDocRender(new CPDF_DocRenderData(this)),
- m_pByteStringPool(pdfium::MakeUnique<CFX_ByteStringPool>()) {
- if (pParser)
- SetLastObjNum(m_pParser->GetLastObjNum());
-}
-
-CPDF_Document::~CPDF_Document() {
- delete m_pDocPage;
- CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this);
- m_pByteStringPool.DeleteObject(); // Make weak.
-}
-
-CPDF_Object* CPDF_Document::ParseIndirectObject(uint32_t objnum) {
- return m_pParser ? m_pParser->ParseIndirectObject(this, objnum) : nullptr;
-}
-
-void CPDF_Document::LoadDocInternal() {
- SetLastObjNum(m_pParser->GetLastObjNum());
-
- CPDF_Object* pRootObj = GetOrParseIndirectObject(m_pParser->GetRootObjNum());
- if (!pRootObj)
- return;
-
- m_pRootDict = pRootObj->GetDict();
- if (!m_pRootDict)
- return;
-
- CPDF_Object* pInfoObj = GetOrParseIndirectObject(m_pParser->GetInfoObjNum());
- if (pInfoObj)
- m_pInfoDict = pInfoObj->GetDict();
-}
-
-void CPDF_Document::LoadDoc() {
- LoadDocInternal();
- m_PageList.SetSize(RetrievePageCount());
-}
-
-void CPDF_Document::LoadLinearizedDoc(CPDF_Dictionary* pLinearizationParams) {
- m_bLinearized = true;
- LoadDocInternal();
-
- uint32_t dwPageCount = 0;
- CPDF_Object* pCount = pLinearizationParams->GetObjectFor("N");
- if (ToNumber(pCount))
- dwPageCount = pCount->GetInteger();
- m_PageList.SetSize(dwPageCount);
-
- CPDF_Object* pNo = pLinearizationParams->GetObjectFor("P");
- if (ToNumber(pNo))
- m_iFirstPageNo = pNo->GetInteger();
-
- CPDF_Object* pObjNum = pLinearizationParams->GetObjectFor("O");
- if (ToNumber(pObjNum))
- m_dwFirstPageObjNum = pObjNum->GetInteger();
-}
-
-void CPDF_Document::LoadPages() {
- m_PageList.SetSize(RetrievePageCount());
-}
-
-CPDF_Dictionary* CPDF_Document::FindPDFPage(CPDF_Dictionary* pPages,
- int iPage,
- int nPagesToGo,
- int level) {
- CPDF_Array* pKidList = pPages->GetArrayFor("Kids");
- if (!pKidList)
- return nPagesToGo == 0 ? pPages : nullptr;
-
- if (level >= FX_MAX_PAGE_LEVEL)
- return nullptr;
-
- for (size_t i = 0; i < pKidList->GetCount(); i++) {
- CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
- if (!pKid) {
- nPagesToGo--;
- continue;
- }
- if (pKid == pPages)
- continue;
- if (!pKid->KeyExist("Kids")) {
- if (nPagesToGo == 0)
- return pKid;
-
- m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum());
- nPagesToGo--;
- } else {
- int nPages = pKid->GetIntegerFor("Count");
- if (nPagesToGo < nPages)
- return FindPDFPage(pKid, iPage, nPagesToGo, level + 1);
-
- nPagesToGo -= nPages;
- }
- }
- return nullptr;
-}
-
-CPDF_Dictionary* CPDF_Document::GetPagesDict() const {
- CPDF_Dictionary* pRoot = GetRoot();
- return pRoot ? pRoot->GetDictFor("Pages") : nullptr;
-}
-
-bool CPDF_Document::IsPageLoaded(int iPage) const {
- return !!m_PageList.GetAt(iPage);
-}
-
-CPDF_Dictionary* CPDF_Document::GetPage(int iPage) {
- if (iPage < 0 || iPage >= m_PageList.GetSize())
- return nullptr;
-
- if (m_bLinearized && (iPage == m_iFirstPageNo)) {
- if (CPDF_Dictionary* pDict =
- ToDictionary(GetOrParseIndirectObject(m_dwFirstPageObjNum))) {
- return pDict;
- }
- }
-
- int objnum = m_PageList.GetAt(iPage);
- if (objnum) {
- if (CPDF_Dictionary* pDict = ToDictionary(GetOrParseIndirectObject(objnum)))
- return pDict;
- }
-
- CPDF_Dictionary* pPages = GetPagesDict();
- if (!pPages)
- return nullptr;
-
- CPDF_Dictionary* pPage = FindPDFPage(pPages, iPage, iPage, 0);
- if (!pPage)
- return nullptr;
-
- m_PageList.SetAt(iPage, pPage->GetObjNum());
- return pPage;
-}
-
-void CPDF_Document::SetPageObjNum(int iPage, uint32_t objNum) {
- m_PageList.SetAt(iPage, objNum);
-}
-
-int CPDF_Document::FindPageIndex(CPDF_Dictionary* pNode,
- uint32_t& skip_count,
- uint32_t objnum,
- int& index,
- int level) {
- if (!pNode->KeyExist("Kids")) {
- if (objnum == pNode->GetObjNum())
- return index;
-
- if (skip_count)
- skip_count--;
-
- index++;
- return -1;
- }
-
- CPDF_Array* pKidList = pNode->GetArrayFor("Kids");
- if (!pKidList)
- return -1;
-
- if (level >= FX_MAX_PAGE_LEVEL)
- return -1;
-
- size_t count = pNode->GetIntegerFor("Count");
- if (count <= skip_count) {
- skip_count -= count;
- index += count;
- return -1;
- }
-
- if (count && count == pKidList->GetCount()) {
- for (size_t i = 0; i < count; i++) {
- if (CPDF_Reference* pKid = ToReference(pKidList->GetObjectAt(i))) {
- if (pKid->GetRefObjNum() == objnum) {
- m_PageList.SetAt(index + i, objnum);
- return static_cast<int>(index + i);
- }
- }
- }
- }
-
- for (size_t i = 0; i < pKidList->GetCount(); i++) {
- CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
- if (!pKid || pKid == pNode)
- continue;
-
- int found_index = FindPageIndex(pKid, skip_count, objnum, index, level + 1);
- if (found_index >= 0)
- return found_index;
- }
- return -1;
-}
-
-int CPDF_Document::GetPageIndex(uint32_t objnum) {
- uint32_t nPages = m_PageList.GetSize();
- uint32_t skip_count = 0;
- bool bSkipped = false;
- for (uint32_t i = 0; i < nPages; i++) {
- uint32_t objnum1 = m_PageList.GetAt(i);
- if (objnum1 == objnum)
- return i;
-
- if (!bSkipped && objnum1 == 0) {
- skip_count = i;
- bSkipped = true;
- }
- }
- CPDF_Dictionary* pPages = GetPagesDict();
- if (!pPages)
- return -1;
-
- int index = 0;
- return FindPageIndex(pPages, skip_count, objnum, index);
-}
-
-int CPDF_Document::GetPageCount() const {
- return m_PageList.GetSize();
-}
-
-int CPDF_Document::RetrievePageCount() const {
- CPDF_Dictionary* pPages = GetPagesDict();
- if (!pPages)
- return 0;
-
- if (!pPages->KeyExist("Kids"))
- return 1;
-
- std::set<CPDF_Dictionary*> visited_pages;
- visited_pages.insert(pPages);
- return CountPages(pPages, &visited_pages);
-}
-
-uint32_t CPDF_Document::GetUserPermissions() const {
- // https://bugs.chromium.org/p/pdfium/issues/detail?id=499
- if (!m_pParser) {
-#ifndef PDF_ENABLE_XFA
- return 0;
-#else // PDF_ENABLE_XFA
- return 0xFFFFFFFF;
-#endif
- }
- return m_pParser->GetPermissions();
-}
-
-CPDF_Font* CPDF_Document::LoadFont(CPDF_Dictionary* pFontDict) {
- ASSERT(pFontDict);
- return m_pDocPage->GetFont(pFontDict, FALSE);
-}
-
-CPDF_StreamAcc* CPDF_Document::LoadFontFile(CPDF_Stream* pStream) {
- return m_pDocPage->GetFontFileStreamAcc(pStream);
-}
-
-CPDF_ColorSpace* CPDF_Document::LoadColorSpace(CPDF_Object* pCSObj,
- CPDF_Dictionary* pResources) {
- return m_pDocPage->GetColorSpace(pCSObj, pResources);
-}
-
-CPDF_Pattern* CPDF_Document::LoadPattern(CPDF_Object* pPatternObj,
- FX_BOOL bShading,
- const CFX_Matrix& matrix) {
- return m_pDocPage->GetPattern(pPatternObj, bShading, matrix);
-}
-
-CPDF_IccProfile* CPDF_Document::LoadIccProfile(CPDF_Stream* pStream) {
- return m_pDocPage->GetIccProfile(pStream);
-}
-
-CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj) {
- if (!pObj)
- return nullptr;
-
- ASSERT(pObj->GetObjNum());
- return m_pDocPage->GetImage(pObj);
-}
-
-void CPDF_Document::CreateNewDoc() {
- ASSERT(!m_pRootDict && !m_pInfoDict);
- m_pRootDict = new CPDF_Dictionary(m_pByteStringPool);
- m_pRootDict->SetNameFor("Type", "Catalog");
- AddIndirectObject(m_pRootDict);
-
- CPDF_Dictionary* pPages = new CPDF_Dictionary(m_pByteStringPool);
- pPages->SetNameFor("Type", "Pages");
- pPages->SetNumberFor("Count", 0);
- pPages->SetFor("Kids", new CPDF_Array);
- m_pRootDict->SetReferenceFor("Pages", this, AddIndirectObject(pPages));
- m_pInfoDict = new CPDF_Dictionary(m_pByteStringPool);
- AddIndirectObject(m_pInfoDict);
-}
-
-CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) {
- CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pByteStringPool);
- pDict->SetNameFor("Type", "Page");
- uint32_t dwObjNum = AddIndirectObject(pDict);
- if (InsertNewPage(this, iPage, pDict, m_PageList) < 0) {
- ReleaseIndirectObject(dwObjNum);
- return nullptr;
- }
- return pDict;
-}
-
-void CPDF_Document::DeletePage(int iPage) {
- CPDF_Dictionary* pPages = GetPagesDict();
- if (!pPages)
- return;
-
- int nPages = pPages->GetIntegerFor("Count");
- if (iPage < 0 || iPage >= nPages)
- return;
-
- std::set<CPDF_Dictionary*> stack = {pPages};
- if (InsertDeletePDFPage(this, pPages, iPage, nullptr, FALSE, &stack) < 0)
- return;
-
- m_PageList.RemoveAt(iPage);
-}
-
-CPDF_Font* CPDF_Document::AddStandardFont(const FX_CHAR* font,
- CPDF_FontEncoding* pEncoding) {
- CFX_ByteString name(font);
- if (PDF_GetStandardFontName(&name) < 0)
- return nullptr;
- return GetPageData()->GetStandardFont(name, pEncoding);
-}
-
-size_t CPDF_Document::CalculateEncodingDict(int charset,
- CPDF_Dictionary* pBaseDict) {
- size_t i;
- for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) {
- if (g_FX_CharsetUnicodes[i].m_Charset == charset)
- break;
- }
- if (i == FX_ArraySize(g_FX_CharsetUnicodes))
- return i;
- CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary(m_pByteStringPool);
- pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding");
- CPDF_Array* pArray = new CPDF_Array;
- pArray->AddInteger(128);
- const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
- for (int j = 0; j < 128; j++) {
- CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
- pArray->AddName(name.IsEmpty() ? ".notdef" : name);
- }
- pEncodingDict->SetFor("Differences", pArray);
- pBaseDict->SetReferenceFor("Encoding", this,
- AddIndirectObject(pEncodingDict));
-
- return i;
-}
-
-CPDF_Dictionary* CPDF_Document::ProcessbCJK(
- CPDF_Dictionary* pBaseDict,
- int charset,
- FX_BOOL bVert,
- CFX_ByteString basefont,
- std::function<void(FX_WCHAR, FX_WCHAR, CPDF_Array*)> Insert) {
- CPDF_Dictionary* pFontDict = new CPDF_Dictionary(m_pByteStringPool);
- CFX_ByteString cmap;
- CFX_ByteString ordering;
- int supplement = 0;
- CPDF_Array* pWidthArray = new CPDF_Array;
- switch (charset) {
- case FXFONT_CHINESEBIG5_CHARSET:
- cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
- ordering = "CNS1";
- supplement = 4;
- pWidthArray->AddInteger(1);
- Insert(0x20, 0x7e, pWidthArray);
- break;
- case FXFONT_GB2312_CHARSET:
- cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
- ordering = "GB1";
- supplement = 2;
- pWidthArray->AddInteger(7716);
- Insert(0x20, 0x20, pWidthArray);
- pWidthArray->AddInteger(814);
- Insert(0x21, 0x7e, pWidthArray);
- break;
- case FXFONT_HANGUL_CHARSET:
- cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
- ordering = "Korea1";
- supplement = 2;
- pWidthArray->AddInteger(1);
- Insert(0x20, 0x7e, pWidthArray);
- break;
- case FXFONT_SHIFTJIS_CHARSET:
- cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
- ordering = "Japan1";
- supplement = 5;
- pWidthArray->AddInteger(231);
- Insert(0x20, 0x7d, pWidthArray);
- pWidthArray->AddInteger(326);
- Insert(0xa0, 0xa0, pWidthArray);
- pWidthArray->AddInteger(327);
- Insert(0xa1, 0xdf, pWidthArray);
- pWidthArray->AddInteger(631);
- Insert(0x7e, 0x7e, pWidthArray);
- break;
- }
- pBaseDict->SetNameFor("Subtype", "Type0");
- pBaseDict->SetNameFor("BaseFont", basefont);
- pBaseDict->SetNameFor("Encoding", cmap);
- pFontDict->SetFor("W", pWidthArray);
- pFontDict->SetNameFor("Type", "Font");
- pFontDict->SetNameFor("Subtype", "CIDFontType2");
- pFontDict->SetNameFor("BaseFont", basefont);
- CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary(m_pByteStringPool);
- pCIDSysInfo->SetStringFor("Registry", "Adobe");
- pCIDSysInfo->SetStringFor("Ordering", ordering);
- pCIDSysInfo->SetIntegerFor("Supplement", supplement);
- pFontDict->SetFor("CIDSystemInfo", pCIDSysInfo);
- CPDF_Array* pArray = new CPDF_Array;
- pBaseDict->SetFor("DescendantFonts", pArray);
- pArray->AddReference(this, AddIndirectObject(pFontDict));
- return pFontDict;
-}
-
-CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) {
- if (!pFont)
- return nullptr;
-
- bool bCJK = charset == FXFONT_CHINESEBIG5_CHARSET ||
- charset == FXFONT_GB2312_CHARSET ||
- charset == FXFONT_HANGUL_CHARSET ||
- charset == FXFONT_SHIFTJIS_CHARSET;
- CFX_ByteString basefont = pFont->GetFamilyName();
- basefont.Replace(" ", "");
- int flags =
- CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(),
- false, false, charset == FXFONT_SYMBOL_CHARSET);
-
- CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool);
- pBaseDict->SetNameFor("Type", "Font");
- std::unique_ptr<CFX_UnicodeEncoding> pEncoding(
- new CFX_UnicodeEncoding(pFont));
- CPDF_Dictionary* pFontDict = pBaseDict;
- if (!bCJK) {
- CPDF_Array* pWidths = new CPDF_Array;
- for (int charcode = 32; charcode < 128; charcode++) {
- int glyph_index = pEncoding->GlyphFromCharCode(charcode);
- int char_width = pFont->GetGlyphWidth(glyph_index);
- pWidths->AddInteger(char_width);
- }
- if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET ||
- charset == FXFONT_SYMBOL_CHARSET) {
- pBaseDict->SetNameFor("Encoding", "WinAnsiEncoding");
- for (int charcode = 128; charcode <= 255; charcode++) {
- int glyph_index = pEncoding->GlyphFromCharCode(charcode);
- int char_width = pFont->GetGlyphWidth(glyph_index);
- pWidths->AddInteger(char_width);
- }
- } else {
- size_t i = CalculateEncodingDict(charset, pBaseDict);
- if (i < FX_ArraySize(g_FX_CharsetUnicodes)) {
- const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
- for (int j = 0; j < 128; j++) {
- int glyph_index = pEncoding->GlyphFromCharCode(pUnicodes[j]);
- int char_width = pFont->GetGlyphWidth(glyph_index);
- pWidths->AddInteger(char_width);
- }
- }
- }
- ProcessNonbCJK(pBaseDict, pFont->IsBold(), pFont->IsItalic(), basefont,
- pWidths);
- } else {
- pFontDict = ProcessbCJK(pBaseDict, charset, bVert, basefont,
- [pFont, &pEncoding](FX_WCHAR start, FX_WCHAR end,
- CPDF_Array* widthArr) {
- InsertWidthArray1(pFont, pEncoding.get(), start,
- end, widthArr);
- });
- }
- AddIndirectObject(pBaseDict);
- int italicangle =
- pFont->GetSubstFont() ? pFont->GetSubstFont()->m_ItalicAngle : 0;
- FX_RECT bbox;
- pFont->GetBBox(bbox);
- CPDF_Array* pBBox = new CPDF_Array;
- pBBox->AddInteger(bbox.left);
- pBBox->AddInteger(bbox.bottom);
- pBBox->AddInteger(bbox.right);
- pBBox->AddInteger(bbox.top);
- int32_t nStemV = 0;
- if (pFont->GetSubstFont()) {
- nStemV = pFont->GetSubstFont()->m_Weight / 5;
- } else {
- static const FX_CHAR stem_chars[] = {'i', 'I', '!', '1'};
- const size_t count = FX_ArraySize(stem_chars);
- uint32_t glyph = pEncoding->GlyphFromCharCode(stem_chars[0]);
- nStemV = pFont->GetGlyphWidth(glyph);
- for (size_t i = 1; i < count; i++) {
- glyph = pEncoding->GlyphFromCharCode(stem_chars[i]);
- int width = pFont->GetGlyphWidth(glyph);
- if (width > 0 && width < nStemV)
- nStemV = width;
- }
- }
- CPDF_Dictionary* pFontDesc =
- CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(),
- pFont->GetDescent(), pBBox, nStemV);
- pFontDict->SetReferenceFor("FontDescriptor", this,
- AddIndirectObject(pFontDesc));
- return LoadFont(pBaseDict);
-}
-
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
-CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTW* pLogFont,
- FX_BOOL bVert,
- FX_BOOL bTranslateName) {
- LOGFONTA lfa;
- FXSYS_memcpy(&lfa, pLogFont, (char*)lfa.lfFaceName - (char*)&lfa);
- CFX_ByteString face = CFX_ByteString::FromUnicode(pLogFont->lfFaceName);
- if (face.GetLength() >= LF_FACESIZE)
- return nullptr;
-
- FXSYS_strcpy(lfa.lfFaceName, face.c_str());
- return AddWindowsFont(&lfa, bVert, bTranslateName);
-}
-
-CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont,
- FX_BOOL bVert,
- FX_BOOL bTranslateName) {
- pLogFont->lfHeight = -1000;
- pLogFont->lfWidth = 0;
- HGDIOBJ hFont = CreateFontIndirectA(pLogFont);
- HDC hDC = CreateCompatibleDC(nullptr);
- hFont = SelectObject(hDC, hFont);
- int tm_size = GetOutlineTextMetrics(hDC, 0, nullptr);
- if (tm_size == 0) {
- hFont = SelectObject(hDC, hFont);
- DeleteObject(hFont);
- DeleteDC(hDC);
- return nullptr;
- }
-
- LPBYTE tm_buf = FX_Alloc(BYTE, tm_size);
- OUTLINETEXTMETRIC* ptm = reinterpret_cast<OUTLINETEXTMETRIC*>(tm_buf);
- GetOutlineTextMetrics(hDC, tm_size, ptm);
- int flags = CalculateFlags(false, pLogFont->lfItalic != 0,
- (pLogFont->lfPitchAndFamily & 3) == FIXED_PITCH,
- (pLogFont->lfPitchAndFamily & 0xf8) == FF_ROMAN,
- (pLogFont->lfPitchAndFamily & 0xf8) == FF_SCRIPT,
- pLogFont->lfCharSet == FXFONT_SYMBOL_CHARSET);
-
- bool bCJK = pLogFont->lfCharSet == FXFONT_CHINESEBIG5_CHARSET ||
- pLogFont->lfCharSet == FXFONT_GB2312_CHARSET ||
- pLogFont->lfCharSet == FXFONT_HANGUL_CHARSET ||
- pLogFont->lfCharSet == FXFONT_SHIFTJIS_CHARSET;
- CFX_ByteString basefont;
- if (bTranslateName && bCJK)
- basefont = FPDF_GetPSNameFromTT(hDC);
-
- if (basefont.IsEmpty())
- basefont = pLogFont->lfFaceName;
-
- int italicangle = ptm->otmItalicAngle / 10;
- int ascend = ptm->otmrcFontBox.top;
- int descend = ptm->otmrcFontBox.bottom;
- int capheight = ptm->otmsCapEmHeight;
- int bbox[4] = {ptm->otmrcFontBox.left, ptm->otmrcFontBox.bottom,
- ptm->otmrcFontBox.right, ptm->otmrcFontBox.top};
- FX_Free(tm_buf);
- basefont.Replace(" ", "");
- CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool);
- pBaseDict->SetNameFor("Type", "Font");
- CPDF_Dictionary* pFontDict = pBaseDict;
- if (!bCJK) {
- if (pLogFont->lfCharSet == FXFONT_ANSI_CHARSET ||
- pLogFont->lfCharSet == FXFONT_DEFAULT_CHARSET ||
- pLogFont->lfCharSet == FXFONT_SYMBOL_CHARSET) {
- pBaseDict->SetNameFor("Encoding", "WinAnsiEncoding");
- } else {
- CalculateEncodingDict(pLogFont->lfCharSet, pBaseDict);
- }
- int char_widths[224];
- GetCharWidth(hDC, 32, 255, char_widths);
- CPDF_Array* pWidths = new CPDF_Array;
- for (size_t i = 0; i < 224; i++)
- pWidths->AddInteger(char_widths[i]);
- ProcessNonbCJK(pBaseDict, pLogFont->lfWeight > FW_MEDIUM,
- pLogFont->lfItalic != 0, basefont, pWidths);
- } else {
- pFontDict =
- ProcessbCJK(pBaseDict, pLogFont->lfCharSet, bVert, basefont,
- [&hDC](FX_WCHAR start, FX_WCHAR end, CPDF_Array* widthArr) {
- InsertWidthArray(hDC, start, end, widthArr);
- });
- }
- AddIndirectObject(pBaseDict);
- CPDF_Array* pBBox = new CPDF_Array;
- for (int i = 0; i < 4; i++)
- pBBox->AddInteger(bbox[i]);
- CPDF_Dictionary* pFontDesc =
- CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend,
- pBBox, pLogFont->lfWeight / 5);
- pFontDesc->SetIntegerFor("CapHeight", capheight);
- pFontDict->SetReferenceFor("FontDescriptor", this,
- AddIndirectObject(pFontDesc));
- hFont = SelectObject(hDC, hFont);
- DeleteObject(hFont);
- DeleteDC(hDC);
- return LoadFont(pBaseDict);
-}
-#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_document.h b/core/fpdfapi/fpdf_parser/cpdf_document.h
deleted file mode 100644
index 9ae43f7e03..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_document.h
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_DOCUMENT_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_DOCUMENT_H_
-
-#include <functional>
-#include <memory>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-#include "core/fpdfdoc/cpdf_linklist.h"
-#include "core/fxcrt/cfx_string_pool_template.h"
-#include "core/fxcrt/cfx_weak_ptr.h"
-#include "core/fxcrt/fx_basic.h"
-
-class CFX_Font;
-class CFX_Matrix;
-class CPDF_ColorSpace;
-class CPDF_DocPageData;
-class CPDF_DocRenderData;
-class CPDF_Font;
-class CPDF_FontEncoding;
-class CPDF_IccProfile;
-class CPDF_Image;
-class CPDF_Parser;
-class CPDF_Pattern;
-class CPDF_StreamAcc;
-class JBig2_DocumentContext;
-
-#define FPDFPERM_PRINT 0x0004
-#define FPDFPERM_MODIFY 0x0008
-#define FPDFPERM_EXTRACT 0x0010
-#define FPDFPERM_ANNOT_FORM 0x0020
-#define FPDFPERM_FILL_FORM 0x0100
-#define FPDFPERM_EXTRACT_ACCESS 0x0200
-#define FPDFPERM_ASSEMBLE 0x0400
-#define FPDFPERM_PRINT_HIGH 0x0800
-#define FPDF_PAGE_MAX_NUM 0xFFFFF
-
-class CPDF_Document : public CPDF_IndirectObjectHolder {
- public:
- explicit CPDF_Document(std::unique_ptr<CPDF_Parser> pParser);
- ~CPDF_Document() override;
-
- CPDF_Parser* GetParser() const { return m_pParser.get(); }
- CPDF_Dictionary* GetRoot() const { return m_pRootDict; }
- CPDF_Dictionary* GetInfo() const { return m_pInfoDict; }
- CFX_WeakPtr<CFX_ByteStringPool> GetByteStringPool() const {
- return m_pByteStringPool;
- }
-
- void DeletePage(int iPage);
- int GetPageCount() const;
-
- bool IsPageLoaded(int iPage) const;
- CPDF_Dictionary* GetPage(int iPage);
- int GetPageIndex(uint32_t objnum);
- uint32_t GetUserPermissions() const;
- CPDF_DocPageData* GetPageData() const { return m_pDocPage; }
-
- void SetPageObjNum(int iPage, uint32_t objNum);
-
- std::unique_ptr<JBig2_DocumentContext>* CodecContext() {
- return &m_pCodecContext;
- }
- std::unique_ptr<CPDF_LinkList>* LinksContext() { return &m_pLinksContext; }
-
- CPDF_DocRenderData* GetRenderData() const { return m_pDocRender.get(); }
-
- // |pFontDict| must not be null.
- CPDF_Font* LoadFont(CPDF_Dictionary* pFontDict);
- CPDF_ColorSpace* LoadColorSpace(CPDF_Object* pCSObj,
- CPDF_Dictionary* pResources = nullptr);
-
- CPDF_Pattern* LoadPattern(CPDF_Object* pObj,
- FX_BOOL bShading,
- const CFX_Matrix& matrix);
-
- CPDF_Image* LoadImageF(CPDF_Object* pObj);
- CPDF_StreamAcc* LoadFontFile(CPDF_Stream* pStream);
- CPDF_IccProfile* LoadIccProfile(CPDF_Stream* pStream);
-
- void LoadDoc();
- void LoadLinearizedDoc(CPDF_Dictionary* pLinearizationParams);
- void LoadPages();
-
- void CreateNewDoc();
- CPDF_Dictionary* CreateNewPage(int iPage);
-
- CPDF_Font* AddStandardFont(const FX_CHAR* font, CPDF_FontEncoding* pEncoding);
- CPDF_Font* AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert);
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
- CPDF_Font* AddWindowsFont(LOGFONTA* pLogFont,
- FX_BOOL bVert,
- FX_BOOL bTranslateName = FALSE);
- CPDF_Font* AddWindowsFont(LOGFONTW* pLogFont,
- FX_BOOL bVert,
- FX_BOOL bTranslateName = FALSE);
-#endif
-
- private:
- friend class CPDF_TestDocument;
-
- // Retrieve page count information by getting count value from the tree nodes
- int RetrievePageCount() const;
- CPDF_Dictionary* FindPDFPage(CPDF_Dictionary* pPages,
- int iPage,
- int nPagesToGo,
- int level);
- int FindPageIndex(CPDF_Dictionary* pNode,
- uint32_t& skip_count,
- uint32_t objnum,
- int& index,
- int level = 0);
- CPDF_Object* ParseIndirectObject(uint32_t objnum) override;
- void LoadDocInternal();
- size_t CalculateEncodingDict(int charset, CPDF_Dictionary* pBaseDict);
- CPDF_Dictionary* GetPagesDict() const;
- CPDF_Dictionary* ProcessbCJK(
- CPDF_Dictionary* pBaseDict,
- int charset,
- FX_BOOL bVert,
- CFX_ByteString basefont,
- std::function<void(FX_WCHAR, FX_WCHAR, CPDF_Array*)> Insert);
-
- std::unique_ptr<CPDF_Parser> m_pParser;
- CPDF_Dictionary* m_pRootDict;
- CPDF_Dictionary* m_pInfoDict;
- bool m_bLinearized;
- int m_iFirstPageNo;
- uint32_t m_dwFirstPageObjNum;
- // TODO(thestig): Figure out why this cannot be a std::unique_ptr.
- CPDF_DocPageData* m_pDocPage;
- std::unique_ptr<CPDF_DocRenderData> m_pDocRender;
- std::unique_ptr<JBig2_DocumentContext> m_pCodecContext;
- std::unique_ptr<CPDF_LinkList> m_pLinksContext;
- CFX_ArrayTemplate<uint32_t> m_PageList;
- CFX_WeakPtr<CFX_ByteStringPool> m_pByteStringPool;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_DOCUMENT_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp b/core/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp
deleted file mode 100644
index ae602b252d..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_hint_tables.cpp
+++ /dev/null
@@ -1,524 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_hint_tables.h"
-
-#include <limits>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_data_avail.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_document.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h"
-#include "core/fxcrt/fx_safe_types.h"
-#include "third_party/base/numerics/safe_conversions.h"
-
-namespace {
-
-bool CanReadFromBitStream(const CFX_BitStream* hStream,
- const FX_SAFE_UINT32& bits) {
- return bits.IsValid() && hStream->BitsRemaining() >= bits.ValueOrDie();
-}
-
-// Sanity check values from the page table header. The note in the PDF 1.7
-// reference for Table F.3 says the valid range is only 0 through 32. Though 0
-// is not useful either.
-bool IsValidPageOffsetHintTableBitCount(uint32_t bits) {
- return bits > 0 && bits <= 32;
-}
-
-} // namespace
-
-CPDF_HintTables::CPDF_HintTables(CPDF_DataAvail* pDataAvail,
- CPDF_Dictionary* pLinearized)
- : m_pDataAvail(pDataAvail),
- m_pLinearizedDict(pLinearized),
- m_nFirstPageSharedObjs(0),
- m_szFirstPageObjOffset(0) {
- ASSERT(m_pLinearizedDict);
-}
-
-CPDF_HintTables::~CPDF_HintTables() {}
-
-uint32_t CPDF_HintTables::GetItemLength(
- uint32_t index,
- const std::vector<FX_FILESIZE>& szArray) {
- if (szArray.size() < 2 || index > szArray.size() - 2 ||
- szArray[index] > szArray[index + 1]) {
- return 0;
- }
- return szArray[index + 1] - szArray[index];
-}
-
-bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
- if (!hStream || hStream->IsEOF())
- return false;
-
- int nStreamOffset = ReadPrimaryHintStreamOffset();
- if (nStreamOffset < 0)
- return false;
-
- int nStreamLen = ReadPrimaryHintStreamLength();
- if (nStreamLen < 1 ||
- !pdfium::base::IsValueInRangeForNumericType<FX_FILESIZE>(nStreamLen)) {
- return false;
- }
-
- const uint32_t kHeaderSize = 288;
- if (hStream->BitsRemaining() < kHeaderSize)
- return false;
-
- // Item 1: The least number of objects in a page.
- const uint32_t dwObjLeastNum = hStream->GetBits(32);
- if (!dwObjLeastNum)
- return false;
-
- // Item 2: The location of the first page's page object.
- const uint32_t dwFirstObjLoc = hStream->GetBits(32);
- if (dwFirstObjLoc > static_cast<uint32_t>(nStreamOffset)) {
- FX_SAFE_FILESIZE safeLoc = nStreamLen;
- safeLoc += dwFirstObjLoc;
- if (!safeLoc.IsValid())
- return false;
- m_szFirstPageObjOffset = safeLoc.ValueOrDie();
- } else {
- if (!pdfium::base::IsValueInRangeForNumericType<FX_FILESIZE>(dwFirstObjLoc))
- return false;
- m_szFirstPageObjOffset = dwFirstObjLoc;
- }
-
- // Item 3: The number of bits needed to represent the difference
- // between the greatest and least number of objects in a page.
- const uint32_t dwDeltaObjectsBits = hStream->GetBits(16);
- if (!IsValidPageOffsetHintTableBitCount(dwDeltaObjectsBits))
- return false;
-
- // Item 4: The least length of a page in bytes.
- const uint32_t dwPageLeastLen = hStream->GetBits(32);
- if (!dwPageLeastLen)
- return false;
-
- // Item 5: The number of bits needed to represent the difference
- // between the greatest and least length of a page, in bytes.
- const uint32_t dwDeltaPageLenBits = hStream->GetBits(16);
- if (!IsValidPageOffsetHintTableBitCount(dwDeltaPageLenBits))
- return false;
-
- // Skip Item 6, 7, 8, 9 total 96 bits.
- hStream->SkipBits(96);
-
- // Item 10: The number of bits needed to represent the greatest
- // number of shared object references.
- const uint32_t dwSharedObjBits = hStream->GetBits(16);
- if (!IsValidPageOffsetHintTableBitCount(dwSharedObjBits))
- return false;
-
- // Item 11: The number of bits needed to represent the numerically
- // greatest shared object identifier used by the pages.
- const uint32_t dwSharedIdBits = hStream->GetBits(16);
- if (!IsValidPageOffsetHintTableBitCount(dwSharedIdBits))
- return false;
-
- // Item 12: The number of bits needed to represent the numerator of
- // the fractional position for each shared object reference. For each
- // shared object referenced from a page, there is an indication of
- // where in the page's content stream the object is first referenced.
- const uint32_t dwSharedNumeratorBits = hStream->GetBits(16);
- if (!IsValidPageOffsetHintTableBitCount(dwSharedNumeratorBits))
- return false;
-
- // Item 13: Skip Item 13 which has 16 bits.
- hStream->SkipBits(16);
-
- const int nPages = GetNumberOfPages();
- if (nPages < 1 || nPages >= FPDF_PAGE_MAX_NUM)
- return false;
-
- const uint32_t dwPages = pdfium::base::checked_cast<uint32_t>(nPages);
- FX_SAFE_UINT32 required_bits = dwDeltaObjectsBits;
- required_bits *= dwPages;
- if (!CanReadFromBitStream(hStream, required_bits))
- return false;
-
- for (int i = 0; i < nPages; ++i) {
- FX_SAFE_UINT32 safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits);
- safeDeltaObj += dwObjLeastNum;
- if (!safeDeltaObj.IsValid())
- return false;
- m_dwDeltaNObjsArray.push_back(safeDeltaObj.ValueOrDie());
- }
- hStream->ByteAlign();
-
- required_bits = dwDeltaPageLenBits;
- required_bits *= dwPages;
- if (!CanReadFromBitStream(hStream, required_bits))
- return false;
-
- std::vector<uint32_t> dwPageLenArray;
- for (int i = 0; i < nPages; ++i) {
- FX_SAFE_UINT32 safePageLen = hStream->GetBits(dwDeltaPageLenBits);
- safePageLen += dwPageLeastLen;
- if (!safePageLen.IsValid())
- return false;
-
- dwPageLenArray.push_back(safePageLen.ValueOrDie());
- }
-
- int nOffsetE = GetEndOfFirstPageOffset();
- if (nOffsetE < 0)
- return false;
-
- int nFirstPageNum = GetFirstPageNumber();
- if (nFirstPageNum < 0 || nFirstPageNum > std::numeric_limits<int>::max() - 1)
- return false;
-
- for (int i = 0; i < nPages; ++i) {
- if (i == nFirstPageNum) {
- m_szPageOffsetArray.push_back(m_szFirstPageObjOffset);
- } else if (i == nFirstPageNum + 1) {
- if (i == 1) {
- m_szPageOffsetArray.push_back(nOffsetE);
- } else {
- m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 2] +
- dwPageLenArray[i - 2]);
- }
- } else {
- if (i == 0) {
- m_szPageOffsetArray.push_back(nOffsetE);
- } else {
- m_szPageOffsetArray.push_back(m_szPageOffsetArray[i - 1] +
- dwPageLenArray[i - 1]);
- }
- }
- }
-
- m_szPageOffsetArray.push_back(m_szPageOffsetArray[nPages - 1] +
- dwPageLenArray[nPages - 1]);
- hStream->ByteAlign();
-
- // Number of shared objects.
- required_bits = dwSharedObjBits;
- required_bits *= dwPages;
- if (!CanReadFromBitStream(hStream, required_bits))
- return false;
-
- for (int i = 0; i < nPages; i++)
- m_dwNSharedObjsArray.push_back(hStream->GetBits(dwSharedObjBits));
- hStream->ByteAlign();
-
- // Array of identifiers, size = nshared_objects.
- for (int i = 0; i < nPages; i++) {
- required_bits = dwSharedIdBits;
- required_bits *= m_dwNSharedObjsArray[i];
- if (!CanReadFromBitStream(hStream, required_bits))
- return false;
-
- for (uint32_t j = 0; j < m_dwNSharedObjsArray[i]; j++)
- m_dwIdentifierArray.push_back(hStream->GetBits(dwSharedIdBits));
- }
- hStream->ByteAlign();
-
- for (int i = 0; i < nPages; i++) {
- FX_SAFE_UINT32 safeSize = m_dwNSharedObjsArray[i];
- safeSize *= dwSharedNumeratorBits;
- if (!CanReadFromBitStream(hStream, safeSize))
- return false;
-
- hStream->SkipBits(safeSize.ValueOrDie());
- }
- hStream->ByteAlign();
-
- FX_SAFE_UINT32 safeTotalPageLen = dwPages;
- safeTotalPageLen *= dwDeltaPageLenBits;
- if (!CanReadFromBitStream(hStream, safeTotalPageLen))
- return false;
-
- hStream->SkipBits(safeTotalPageLen.ValueOrDie());
- hStream->ByteAlign();
- return true;
-}
-
-bool CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream,
- uint32_t offset) {
- if (!hStream || hStream->IsEOF())
- return false;
-
- int nStreamOffset = ReadPrimaryHintStreamOffset();
- int nStreamLen = ReadPrimaryHintStreamLength();
- if (nStreamOffset < 0 || nStreamLen < 1)
- return false;
-
- FX_SAFE_UINT32 bit_offset = offset;
- bit_offset *= 8;
- if (!bit_offset.IsValid() || hStream->GetPos() > bit_offset.ValueOrDie())
- return false;
- hStream->SkipBits(bit_offset.ValueOrDie() - hStream->GetPos());
-
- const uint32_t kHeaderSize = 192;
- if (hStream->BitsRemaining() < kHeaderSize)
- return false;
-
- // Item 1: The object number of the first object in the shared objects
- // section.
- uint32_t dwFirstSharedObjNum = hStream->GetBits(32);
-
- // Item 2: The location of the first object in the shared objects section.
- uint32_t dwFirstSharedObjLoc = hStream->GetBits(32);
- if (dwFirstSharedObjLoc > static_cast<uint32_t>(nStreamOffset))
- dwFirstSharedObjLoc += nStreamLen;
-
- // Item 3: The number of shared object entries for the first page.
- m_nFirstPageSharedObjs = hStream->GetBits(32);
-
- // Item 4: The number of shared object entries for the shared objects
- // section, including the number of shared object entries for the first page.
- uint32_t dwSharedObjTotal = hStream->GetBits(32);
-
- // Item 5: The number of bits needed to represent the greatest number of
- // objects in a shared object group. Skipped.
- hStream->SkipBits(16);
-
- // Item 6: The least length of a shared object group in bytes.
- uint32_t dwGroupLeastLen = hStream->GetBits(32);
-
- // Item 7: The number of bits needed to represent the difference between the
- // greatest and least length of a shared object group, in bytes.
- uint32_t dwDeltaGroupLen = hStream->GetBits(16);
-
- if (dwFirstSharedObjNum >= CPDF_Parser::kMaxObjectNumber ||
- m_nFirstPageSharedObjs >= CPDF_Parser::kMaxObjectNumber ||
- dwSharedObjTotal >= CPDF_Parser::kMaxObjectNumber) {
- return false;
- }
-
- int nFirstPageObjNum = GetFirstPageObjectNumber();
- if (nFirstPageObjNum < 0)
- return false;
-
- uint32_t dwPrevObjLen = 0;
- uint32_t dwCurObjLen = 0;
- FX_SAFE_UINT32 required_bits = dwSharedObjTotal;
- required_bits *= dwDeltaGroupLen;
- if (!CanReadFromBitStream(hStream, required_bits))
- return false;
-
- for (uint32_t i = 0; i < dwSharedObjTotal; ++i) {
- dwPrevObjLen = dwCurObjLen;
- FX_SAFE_UINT32 safeObjLen = hStream->GetBits(dwDeltaGroupLen);
- safeObjLen += dwGroupLeastLen;
- if (!safeObjLen.IsValid())
- return false;
-
- dwCurObjLen = safeObjLen.ValueOrDie();
- if (i < m_nFirstPageSharedObjs) {
- m_dwSharedObjNumArray.push_back(nFirstPageObjNum + i);
- if (i == 0)
- m_szSharedObjOffsetArray.push_back(m_szFirstPageObjOffset);
- } else {
- FX_SAFE_UINT32 safeObjNum = dwFirstSharedObjNum;
- safeObjNum += i - m_nFirstPageSharedObjs;
- if (!safeObjNum.IsValid())
- return false;
-
- m_dwSharedObjNumArray.push_back(safeObjNum.ValueOrDie());
- if (i == m_nFirstPageSharedObjs) {
- FX_SAFE_FILESIZE safeLoc = dwFirstSharedObjLoc;
- if (!safeLoc.IsValid())
- return false;
-
- m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
- }
- }
-
- if (i != 0 && i != m_nFirstPageSharedObjs) {
- FX_SAFE_FILESIZE safeLoc = dwPrevObjLen;
- safeLoc += m_szSharedObjOffsetArray[i - 1];
- if (!safeLoc.IsValid())
- return false;
-
- m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
- }
- }
-
- if (dwSharedObjTotal > 0) {
- FX_SAFE_FILESIZE safeLoc = dwCurObjLen;
- safeLoc += m_szSharedObjOffsetArray[dwSharedObjTotal - 1];
- if (!safeLoc.IsValid())
- return false;
-
- m_szSharedObjOffsetArray.push_back(safeLoc.ValueOrDie());
- }
-
- hStream->ByteAlign();
- if (hStream->BitsRemaining() < dwSharedObjTotal)
- return false;
-
- hStream->SkipBits(dwSharedObjTotal);
- hStream->ByteAlign();
- return true;
-}
-
-bool CPDF_HintTables::GetPagePos(uint32_t index,
- FX_FILESIZE* szPageStartPos,
- FX_FILESIZE* szPageLength,
- uint32_t* dwObjNum) {
- *szPageStartPos = m_szPageOffsetArray[index];
- *szPageLength = GetItemLength(index, m_szPageOffsetArray);
-
- int nFirstPageObjNum = GetFirstPageObjectNumber();
- if (nFirstPageObjNum < 0)
- return false;
-
- int nFirstPageNum = GetFirstPageNumber();
- if (!pdfium::base::IsValueInRangeForNumericType<uint32_t>(nFirstPageNum))
- return false;
-
- uint32_t dwFirstPageNum = static_cast<uint32_t>(nFirstPageNum);
- if (index == dwFirstPageNum) {
- *dwObjNum = nFirstPageObjNum;
- return true;
- }
-
- // The object number of remaining pages starts from 1.
- *dwObjNum = 1;
- for (uint32_t i = 0; i < index; ++i) {
- if (i == dwFirstPageNum)
- continue;
- *dwObjNum += m_dwDeltaNObjsArray[i];
- }
- return true;
-}
-
-CPDF_DataAvail::DocAvailStatus CPDF_HintTables::CheckPage(
- uint32_t index,
- CPDF_DataAvail::DownloadHints* pHints) {
- if (!pHints)
- return CPDF_DataAvail::DataError;
-
- int nFirstPageNum = GetFirstPageNumber();
- if (!pdfium::base::IsValueInRangeForNumericType<uint32_t>(nFirstPageNum))
- return CPDF_DataAvail::DataError;
-
- if (index == static_cast<uint32_t>(nFirstPageNum))
- return CPDF_DataAvail::DataAvailable;
-
- uint32_t dwLength = GetItemLength(index, m_szPageOffsetArray);
- // If two pages have the same offset, it should be treated as an error.
- if (!dwLength)
- return CPDF_DataAvail::DataError;
-
- if (!m_pDataAvail->IsDataAvail(m_szPageOffsetArray[index], dwLength, pHints))
- return CPDF_DataAvail::DataNotAvailable;
-
- // Download data of shared objects in the page.
- uint32_t offset = 0;
- for (uint32_t i = 0; i < index; ++i)
- offset += m_dwNSharedObjsArray[i];
-
- int nFirstPageObjNum = GetFirstPageObjectNumber();
- if (nFirstPageObjNum < 0)
- return CPDF_DataAvail::DataError;
-
- uint32_t dwIndex = 0;
- uint32_t dwObjNum = 0;
- for (uint32_t j = 0; j < m_dwNSharedObjsArray[index]; ++j) {
- dwIndex = m_dwIdentifierArray[offset + j];
- if (dwIndex >= m_dwSharedObjNumArray.size())
- return CPDF_DataAvail::DataNotAvailable;
-
- dwObjNum = m_dwSharedObjNumArray[dwIndex];
- if (dwObjNum >= static_cast<uint32_t>(nFirstPageObjNum) &&
- dwObjNum <
- static_cast<uint32_t>(nFirstPageObjNum) + m_nFirstPageSharedObjs) {
- continue;
- }
-
- dwLength = GetItemLength(dwIndex, m_szSharedObjOffsetArray);
- // If two objects have the same offset, it should be treated as an error.
- if (!dwLength)
- return CPDF_DataAvail::DataError;
-
- if (!m_pDataAvail->IsDataAvail(m_szSharedObjOffsetArray[dwIndex], dwLength,
- pHints)) {
- return CPDF_DataAvail::DataNotAvailable;
- }
- }
- return CPDF_DataAvail::DataAvailable;
-}
-
-bool CPDF_HintTables::LoadHintStream(CPDF_Stream* pHintStream) {
- if (!pHintStream)
- return false;
-
- CPDF_Dictionary* pDict = pHintStream->GetDict();
- CPDF_Object* pOffset = pDict ? pDict->GetObjectFor("S") : nullptr;
- if (!pOffset || !pOffset->IsNumber())
- return false;
-
- int shared_hint_table_offset = pOffset->GetInteger();
- if (shared_hint_table_offset <= 0)
- return false;
-
- CPDF_StreamAcc acc;
- acc.LoadAllData(pHintStream);
-
- uint32_t size = acc.GetSize();
- // The header section of page offset hint table is 36 bytes.
- // The header section of shared object hint table is 24 bytes.
- // Hint table has at least 60 bytes.
- const uint32_t kMinStreamLength = 60;
- if (size < kMinStreamLength)
- return false;
-
- FX_SAFE_UINT32 safe_shared_hint_table_offset = shared_hint_table_offset;
- if (!safe_shared_hint_table_offset.IsValid() ||
- size < safe_shared_hint_table_offset.ValueOrDie()) {
- return false;
- }
-
- CFX_BitStream bs;
- bs.Init(acc.GetData(), size);
- return ReadPageHintTable(&bs) &&
- ReadSharedObjHintTable(&bs, shared_hint_table_offset);
-}
-
-int CPDF_HintTables::GetEndOfFirstPageOffset() const {
- CPDF_Object* pOffsetE = m_pLinearizedDict->GetDirectObjectFor("E");
- return pOffsetE ? pOffsetE->GetInteger() : -1;
-}
-
-int CPDF_HintTables::GetNumberOfPages() const {
- CPDF_Object* pPageNum = m_pLinearizedDict->GetDirectObjectFor("N");
- return pPageNum ? pPageNum->GetInteger() : 0;
-}
-
-int CPDF_HintTables::GetFirstPageObjectNumber() const {
- CPDF_Object* pFirstPageObj = m_pLinearizedDict->GetDirectObjectFor("O");
- return pFirstPageObj ? pFirstPageObj->GetInteger() : -1;
-}
-
-int CPDF_HintTables::GetFirstPageNumber() const {
- CPDF_Object* pFirstPageNum = m_pLinearizedDict->GetDirectObjectFor("P");
- return pFirstPageNum ? pFirstPageNum->GetInteger() : 0;
-}
-
-int CPDF_HintTables::ReadPrimaryHintStreamOffset() const {
- return ReadPrimaryHintStream(0);
-}
-
-int CPDF_HintTables::ReadPrimaryHintStreamLength() const {
- return ReadPrimaryHintStream(1);
-}
-
-int CPDF_HintTables::ReadPrimaryHintStream(int index) const {
- CPDF_Array* pRange = m_pLinearizedDict->GetArrayFor("H");
- if (!pRange)
- return -1;
-
- CPDF_Object* pStreamLen = pRange->GetDirectObjectAt(index);
- return pStreamLen ? pStreamLen->GetInteger() : -1;
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_hint_tables.h b/core/fpdfapi/fpdf_parser/cpdf_hint_tables.h
deleted file mode 100644
index 797cb24f50..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_hint_tables.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_HINT_TABLES_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_HINT_TABLES_H_
-
-#include <vector>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_data_avail.h"
-#include "core/fxcrt/fx_basic.h"
-#include "core/fxcrt/fx_stream.h"
-
-class CFX_BitStream;
-class CPDF_Dictionary;
-class CPDF_Stream;
-
-class CPDF_HintTables {
- public:
- CPDF_HintTables(CPDF_DataAvail* pDataAvail, CPDF_Dictionary* pLinearized);
- virtual ~CPDF_HintTables();
-
- bool GetPagePos(uint32_t index,
- FX_FILESIZE* szPageStartPos,
- FX_FILESIZE* szPageLength,
- uint32_t* dwObjNum);
-
- CPDF_DataAvail::DocAvailStatus CheckPage(
- uint32_t index,
- CPDF_DataAvail::DownloadHints* pHints);
-
- bool LoadHintStream(CPDF_Stream* pHintStream);
-
- protected:
- bool ReadPageHintTable(CFX_BitStream* hStream);
- bool ReadSharedObjHintTable(CFX_BitStream* hStream, uint32_t offset);
-
- private:
- // Tests can override.
- virtual int GetEndOfFirstPageOffset() const;
- virtual int GetNumberOfPages() const;
- virtual int GetFirstPageObjectNumber() const;
- virtual int GetFirstPageNumber() const;
- virtual int ReadPrimaryHintStreamOffset() const;
- virtual int ReadPrimaryHintStreamLength() const;
-
- // Helper for the ReadPrimaryHintStream methods above.
- int ReadPrimaryHintStream(int index) const;
-
- uint32_t GetItemLength(uint32_t index,
- const std::vector<FX_FILESIZE>& szArray);
-
- // Owner, outlives this object.
- CPDF_DataAvail* const m_pDataAvail;
-
- // Owned by |m_pDataAvail|.
- CPDF_Dictionary* const m_pLinearizedDict;
-
- uint32_t m_nFirstPageSharedObjs;
- FX_FILESIZE m_szFirstPageObjOffset;
- std::vector<uint32_t> m_dwDeltaNObjsArray;
- std::vector<uint32_t> m_dwNSharedObjsArray;
- std::vector<uint32_t> m_dwSharedObjNumArray;
- std::vector<uint32_t> m_dwIdentifierArray;
- std::vector<FX_FILESIZE> m_szPageOffsetArray;
- std::vector<FX_FILESIZE> m_szSharedObjOffsetArray;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_HINT_TABLES_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.cpp b/core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.cpp
deleted file mode 100644
index 30d022a36a..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h"
-
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_parser.h"
-
-CPDF_IndirectObjectHolder::CPDF_IndirectObjectHolder() : m_LastObjNum(0) {}
-
-CPDF_IndirectObjectHolder::~CPDF_IndirectObjectHolder() {}
-
-CPDF_Object* CPDF_IndirectObjectHolder::GetIndirectObject(
- uint32_t objnum) const {
- auto it = m_IndirectObjs.find(objnum);
- return it != m_IndirectObjs.end() ? it->second.get() : nullptr;
-}
-
-CPDF_Object* CPDF_IndirectObjectHolder::GetOrParseIndirectObject(
- uint32_t objnum) {
- if (objnum == 0)
- return nullptr;
-
- CPDF_Object* pObj = GetIndirectObject(objnum);
- if (pObj)
- return pObj->GetObjNum() != CPDF_Object::kInvalidObjNum ? pObj : nullptr;
-
- pObj = ParseIndirectObject(objnum);
- if (!pObj)
- return nullptr;
-
- pObj->m_ObjNum = objnum;
- m_LastObjNum = std::max(m_LastObjNum, objnum);
- m_IndirectObjs[objnum].reset(pObj);
- return pObj;
-}
-
-CPDF_Object* CPDF_IndirectObjectHolder::ParseIndirectObject(uint32_t objnum) {
- return nullptr;
-}
-
-uint32_t CPDF_IndirectObjectHolder::AddIndirectObject(CPDF_Object* pObj) {
- if (pObj->m_ObjNum)
- return pObj->m_ObjNum;
-
- m_LastObjNum++;
- m_IndirectObjs[m_LastObjNum].release(); // TODO(tsepez): stop this leak.
- m_IndirectObjs[m_LastObjNum].reset(pObj);
- pObj->m_ObjNum = m_LastObjNum;
- return m_LastObjNum;
-}
-
-bool CPDF_IndirectObjectHolder::ReplaceIndirectObjectIfHigherGeneration(
- uint32_t objnum,
- CPDF_Object* pObj) {
- if (!objnum || !pObj)
- return false;
-
- CPDF_Object* pOldObj = GetIndirectObject(objnum);
- if (pOldObj && pObj->GetGenNum() <= pOldObj->GetGenNum()) {
- delete pObj;
- return false;
- }
- pObj->m_ObjNum = objnum;
- m_IndirectObjs[objnum].reset(pObj);
- m_LastObjNum = std::max(m_LastObjNum, objnum);
- return true;
-}
-
-void CPDF_IndirectObjectHolder::ReleaseIndirectObject(uint32_t objnum) {
- CPDF_Object* pObj = GetIndirectObject(objnum);
- if (!pObj || pObj->GetObjNum() == CPDF_Object::kInvalidObjNum)
- return;
-
- m_IndirectObjs.erase(objnum);
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h b/core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h
deleted file mode 100644
index 8fb91954c3..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_INDIRECT_OBJECT_HOLDER_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_INDIRECT_OBJECT_HOLDER_H_
-
-#include <map>
-#include <memory>
-
-#include "core/fxcrt/fx_system.h"
-
-class CPDF_Object;
-
-class CPDF_IndirectObjectHolder {
- public:
- using const_iterator =
- std::map<uint32_t, std::unique_ptr<CPDF_Object>>::const_iterator;
-
- CPDF_IndirectObjectHolder();
- virtual ~CPDF_IndirectObjectHolder();
-
- CPDF_Object* GetIndirectObject(uint32_t objnum) const;
- CPDF_Object* GetOrParseIndirectObject(uint32_t objnum);
- void ReleaseIndirectObject(uint32_t objnum);
-
- // Take ownership of |pObj|.
- uint32_t AddIndirectObject(CPDF_Object* pObj);
- bool ReplaceIndirectObjectIfHigherGeneration(uint32_t objnum,
- CPDF_Object* pObj);
-
- uint32_t GetLastObjNum() const { return m_LastObjNum; }
- void SetLastObjNum(uint32_t objnum) { m_LastObjNum = objnum; }
-
- const_iterator begin() const { return m_IndirectObjs.begin(); }
- const_iterator end() const { return m_IndirectObjs.end(); }
-
- protected:
- virtual CPDF_Object* ParseIndirectObject(uint32_t objnum);
-
- private:
- uint32_t m_LastObjNum;
- std::map<uint32_t, std::unique_ptr<CPDF_Object>> m_IndirectObjs;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_INDIRECT_OBJECT_HOLDER_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_name.cpp b/core/fpdfapi/fpdf_parser/cpdf_name.cpp
deleted file mode 100644
index 015c3d214a..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_name.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_name.h"
-
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h"
-
-CPDF_Name::CPDF_Name(const CFX_ByteString& str) : m_Name(str) {}
-
-CPDF_Name::~CPDF_Name() {}
-
-CPDF_Object::Type CPDF_Name::GetType() const {
- return NAME;
-}
-
-CPDF_Object* CPDF_Name::Clone() const {
- return new CPDF_Name(m_Name);
-}
-
-CFX_ByteString CPDF_Name::GetString() const {
- return m_Name;
-}
-
-void CPDF_Name::SetString(const CFX_ByteString& str) {
- m_Name = str;
-}
-
-bool CPDF_Name::IsName() const {
- return true;
-}
-
-CPDF_Name* CPDF_Name::AsName() {
- return this;
-}
-
-const CPDF_Name* CPDF_Name::AsName() const {
- return this;
-}
-
-CFX_WideString CPDF_Name::GetUnicodeText() const {
- return PDF_DecodeText(m_Name);
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_name.h b/core/fpdfapi/fpdf_parser/cpdf_name.h
deleted file mode 100644
index 53b8a35d5e..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_name.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_NAME_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_NAME_H_
-
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-
-class CPDF_Name : public CPDF_Object {
- public:
- explicit CPDF_Name(const CFX_ByteString& str);
-
- // CPDF_Object.
- Type GetType() const override;
- CPDF_Object* Clone() const override;
- CFX_ByteString GetString() const override;
- CFX_WideString GetUnicodeText() const override;
- void SetString(const CFX_ByteString& str) override;
- bool IsName() const override;
- CPDF_Name* AsName() override;
- const CPDF_Name* AsName() const override;
-
- protected:
- ~CPDF_Name() override;
-
- CFX_ByteString m_Name;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_NAME_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_null.cpp b/core/fpdfapi/fpdf_parser/cpdf_null.cpp
deleted file mode 100644
index 2149eaff62..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_null.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_null.h"
-
-CPDF_Null::CPDF_Null() {}
-
-CPDF_Object::Type CPDF_Null::GetType() const {
- return NULLOBJ;
-}
-
-CPDF_Object* CPDF_Null::Clone() const {
- return new CPDF_Null;
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_null.h b/core/fpdfapi/fpdf_parser/cpdf_null.h
deleted file mode 100644
index 45d73953ad..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_null.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_NULL_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_NULL_H_
-
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-
-class CPDF_Null : public CPDF_Object {
- public:
- CPDF_Null();
-
- // CPDF_Object.
- Type GetType() const override;
- CPDF_Object* Clone() const override;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_NULL_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_number.cpp b/core/fpdfapi/fpdf_parser/cpdf_number.cpp
deleted file mode 100644
index 28692eabab..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_number.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_number.h"
-
-CPDF_Number::CPDF_Number() : m_bInteger(true), m_Integer(0) {}
-
-CPDF_Number::CPDF_Number(int value) : m_bInteger(true), m_Integer(value) {}
-
-CPDF_Number::CPDF_Number(FX_FLOAT value) : m_bInteger(false), m_Float(value) {}
-
-CPDF_Number::CPDF_Number(const CFX_ByteStringC& str)
- : m_bInteger(FX_atonum(str, &m_Integer)) {}
-
-CPDF_Number::~CPDF_Number() {}
-
-CPDF_Object::Type CPDF_Number::GetType() const {
- return NUMBER;
-}
-
-CPDF_Object* CPDF_Number::Clone() const {
- return m_bInteger ? new CPDF_Number(m_Integer) : new CPDF_Number(m_Float);
-}
-
-FX_FLOAT CPDF_Number::GetNumber() const {
- return m_bInteger ? static_cast<FX_FLOAT>(m_Integer) : m_Float;
-}
-
-int CPDF_Number::GetInteger() const {
- return m_bInteger ? m_Integer : static_cast<int>(m_Float);
-}
-
-bool CPDF_Number::IsNumber() const {
- return true;
-}
-
-CPDF_Number* CPDF_Number::AsNumber() {
- return this;
-}
-
-const CPDF_Number* CPDF_Number::AsNumber() const {
- return this;
-}
-
-void CPDF_Number::SetString(const CFX_ByteString& str) {
- m_bInteger = FX_atonum(str.AsStringC(), &m_Integer);
-}
-
-CFX_ByteString CPDF_Number::GetString() const {
- return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED)
- : CFX_ByteString::FormatFloat(m_Float);
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_number.h b/core/fpdfapi/fpdf_parser/cpdf_number.h
deleted file mode 100644
index 068a9c9594..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_number.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_NUMBER_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_NUMBER_H_
-
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-
-class CPDF_Number : public CPDF_Object {
- public:
- CPDF_Number();
- explicit CPDF_Number(int value);
- explicit CPDF_Number(FX_FLOAT value);
- explicit CPDF_Number(const CFX_ByteStringC& str);
-
- // CPDF_Object.
- Type GetType() const override;
- CPDF_Object* Clone() const override;
- CFX_ByteString GetString() const override;
- FX_FLOAT GetNumber() const override;
- int GetInteger() const override;
- void SetString(const CFX_ByteString& str) override;
- bool IsNumber() const override;
- CPDF_Number* AsNumber() override;
- const CPDF_Number* AsNumber() const override;
-
- bool IsInteger() const { return m_bInteger; }
-
- protected:
- ~CPDF_Number() override;
-
- bool m_bInteger;
- union {
- int m_Integer;
- FX_FLOAT m_Float;
- };
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_NUMBER_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_object.cpp b/core/fpdfapi/fpdf_parser/cpdf_object.cpp
deleted file mode 100644
index ba7490a13f..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_object.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-
-#include <algorithm>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_parser.h"
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h"
-#include "core/fxcrt/fx_string.h"
-#include "third_party/base/stl_util.h"
-
-CPDF_Object::~CPDF_Object() {}
-
-CPDF_Object* CPDF_Object::GetDirect() const {
- return const_cast<CPDF_Object*>(this);
-}
-
-CPDF_Object* CPDF_Object::CloneObjectNonCyclic(bool bDirect) const {
- std::set<const CPDF_Object*> visited_objs;
- return CloneNonCyclic(bDirect, &visited_objs);
-}
-
-CPDF_Object* CPDF_Object::CloneDirectObject() const {
- return CloneObjectNonCyclic(true);
-}
-
-CPDF_Object* CPDF_Object::CloneNonCyclic(
- bool bDirect,
- std::set<const CPDF_Object*>* pVisited) const {
- return Clone();
-}
-
-void CPDF_Object::Release() {
- if (m_ObjNum)
- return;
-
- delete this;
-}
-
-CFX_ByteString CPDF_Object::GetString() const {
- return CFX_ByteString();
-}
-
-CFX_WideString CPDF_Object::GetUnicodeText() const {
- return CFX_WideString();
-}
-
-FX_FLOAT CPDF_Object::GetNumber() const {
- return 0;
-}
-
-int CPDF_Object::GetInteger() const {
- return 0;
-}
-
-CPDF_Dictionary* CPDF_Object::GetDict() const {
- return nullptr;
-}
-
-void CPDF_Object::SetString(const CFX_ByteString& str) {
- ASSERT(FALSE);
-}
-
-bool CPDF_Object::IsArray() const {
- return false;
-}
-
-bool CPDF_Object::IsBoolean() const {
- return false;
-}
-
-bool CPDF_Object::IsDictionary() const {
- return false;
-}
-
-bool CPDF_Object::IsName() const {
- return false;
-}
-
-bool CPDF_Object::IsNumber() const {
- return false;
-}
-
-bool CPDF_Object::IsReference() const {
- return false;
-}
-
-bool CPDF_Object::IsStream() const {
- return false;
-}
-
-bool CPDF_Object::IsString() const {
- return false;
-}
-
-CPDF_Array* CPDF_Object::AsArray() {
- return nullptr;
-}
-
-const CPDF_Array* CPDF_Object::AsArray() const {
- return nullptr;
-}
-
-CPDF_Boolean* CPDF_Object::AsBoolean() {
- return nullptr;
-}
-
-const CPDF_Boolean* CPDF_Object::AsBoolean() const {
- return nullptr;
-}
-
-CPDF_Dictionary* CPDF_Object::AsDictionary() {
- return nullptr;
-}
-
-const CPDF_Dictionary* CPDF_Object::AsDictionary() const {
- return nullptr;
-}
-
-CPDF_Name* CPDF_Object::AsName() {
- return nullptr;
-}
-
-const CPDF_Name* CPDF_Object::AsName() const {
- return nullptr;
-}
-
-CPDF_Number* CPDF_Object::AsNumber() {
- return nullptr;
-}
-
-const CPDF_Number* CPDF_Object::AsNumber() const {
- return nullptr;
-}
-
-CPDF_Reference* CPDF_Object::AsReference() {
- return nullptr;
-}
-
-const CPDF_Reference* CPDF_Object::AsReference() const {
- return nullptr;
-}
-
-CPDF_Stream* CPDF_Object::AsStream() {
- return nullptr;
-}
-
-const CPDF_Stream* CPDF_Object::AsStream() const {
- return nullptr;
-}
-
-CPDF_String* CPDF_Object::AsString() {
- return nullptr;
-}
-
-const CPDF_String* CPDF_Object::AsString() const {
- return nullptr;
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_object.h b/core/fpdfapi/fpdf_parser/cpdf_object.h
deleted file mode 100644
index 7077bc190b..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_object.h
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_OBJECT_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_OBJECT_H_
-
-#include <memory>
-#include <set>
-
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-
-class CPDF_Array;
-class CPDF_Boolean;
-class CPDF_Dictionary;
-class CPDF_Name;
-class CPDF_Null;
-class CPDF_Number;
-class CPDF_Reference;
-class CPDF_Stream;
-class CPDF_String;
-
-class CPDF_Object {
- public:
- static const uint32_t kInvalidObjNum = static_cast<uint32_t>(-1);
- enum Type {
- BOOLEAN = 1,
- NUMBER,
- STRING,
- NAME,
- ARRAY,
- DICTIONARY,
- STREAM,
- NULLOBJ,
- REFERENCE
- };
-
- virtual Type GetType() const = 0;
- uint32_t GetObjNum() const { return m_ObjNum; }
- uint32_t GetGenNum() const { return m_GenNum; }
-
- // Create a deep copy of the object.
- virtual CPDF_Object* Clone() const = 0;
- // Create a deep copy of the object except any reference object be
- // copied to the object it points to directly.
- virtual CPDF_Object* CloneDirectObject() const;
- virtual CPDF_Object* GetDirect() const;
-
- void Release();
-
- virtual CFX_ByteString GetString() const;
- virtual CFX_WideString GetUnicodeText() const;
- virtual FX_FLOAT GetNumber() const;
- virtual int GetInteger() const;
- virtual CPDF_Dictionary* GetDict() const;
-
- virtual void SetString(const CFX_ByteString& str);
-
- virtual bool IsArray() const;
- virtual bool IsBoolean() const;
- virtual bool IsDictionary() const;
- virtual bool IsName() const;
- virtual bool IsNumber() const;
- virtual bool IsReference() const;
- virtual bool IsStream() const;
- virtual bool IsString() const;
-
- virtual CPDF_Array* AsArray();
- virtual const CPDF_Array* AsArray() const;
- virtual CPDF_Boolean* AsBoolean();
- virtual const CPDF_Boolean* AsBoolean() const;
- virtual CPDF_Dictionary* AsDictionary();
- virtual const CPDF_Dictionary* AsDictionary() const;
- virtual CPDF_Name* AsName();
- virtual const CPDF_Name* AsName() const;
- virtual CPDF_Number* AsNumber();
- virtual const CPDF_Number* AsNumber() const;
- virtual CPDF_Reference* AsReference();
- virtual const CPDF_Reference* AsReference() const;
- virtual CPDF_Stream* AsStream();
- virtual const CPDF_Stream* AsStream() const;
- virtual CPDF_String* AsString();
- virtual const CPDF_String* AsString() const;
-
- protected:
- friend class CPDF_Array;
- friend class CPDF_Dictionary;
- friend class CPDF_Document;
- friend class CPDF_IndirectObjectHolder;
- friend class CPDF_Parser;
- friend class CPDF_Reference;
- friend class CPDF_Stream;
- friend struct std::default_delete<CPDF_Object>;
-
- CPDF_Object() : m_ObjNum(0), m_GenNum(0) {}
- virtual ~CPDF_Object();
-
- CPDF_Object* CloneObjectNonCyclic(bool bDirect) const;
-
- // Create a deep copy of the object with the option to either
- // copy a reference object or directly copy the object it refers to
- // when |bDirect| is true.
- // Also check cyclic reference against |pVisited|, no copy if it is found.
- // Complex objects should implement their own CloneNonCyclic()
- // function to properly check for possible loop.
- virtual CPDF_Object* CloneNonCyclic(
- bool bDirect,
- std::set<const CPDF_Object*>* pVisited) const;
-
- uint32_t m_ObjNum;
- uint32_t m_GenNum;
-
- private:
- CPDF_Object(const CPDF_Object& src) {}
-};
-
-inline CPDF_Boolean* ToBoolean(CPDF_Object* obj) {
- return obj ? obj->AsBoolean() : nullptr;
-}
-
-inline const CPDF_Boolean* ToBoolean(const CPDF_Object* obj) {
- return obj ? obj->AsBoolean() : nullptr;
-}
-
-inline CPDF_Number* ToNumber(CPDF_Object* obj) {
- return obj ? obj->AsNumber() : nullptr;
-}
-
-inline const CPDF_Number* ToNumber(const CPDF_Object* obj) {
- return obj ? obj->AsNumber() : nullptr;
-}
-
-inline CPDF_String* ToString(CPDF_Object* obj) {
- return obj ? obj->AsString() : nullptr;
-}
-
-inline const CPDF_String* ToString(const CPDF_Object* obj) {
- return obj ? obj->AsString() : nullptr;
-}
-
-inline CPDF_Name* ToName(CPDF_Object* obj) {
- return obj ? obj->AsName() : nullptr;
-}
-
-inline const CPDF_Name* ToName(const CPDF_Object* obj) {
- return obj ? obj->AsName() : nullptr;
-}
-
-inline CPDF_Array* ToArray(CPDF_Object* obj) {
- return obj ? obj->AsArray() : nullptr;
-}
-
-inline const CPDF_Array* ToArray(const CPDF_Object* obj) {
- return obj ? obj->AsArray() : nullptr;
-}
-
-inline CPDF_Dictionary* ToDictionary(CPDF_Object* obj) {
- return obj ? obj->AsDictionary() : nullptr;
-}
-
-inline const CPDF_Dictionary* ToDictionary(const CPDF_Object* obj) {
- return obj ? obj->AsDictionary() : nullptr;
-}
-inline CPDF_Reference* ToReference(CPDF_Object* obj) {
- return obj ? obj->AsReference() : nullptr;
-}
-
-inline const CPDF_Reference* ToReference(const CPDF_Object* obj) {
- return obj ? obj->AsReference() : nullptr;
-}
-
-inline CPDF_Stream* ToStream(CPDF_Object* obj) {
- return obj ? obj->AsStream() : nullptr;
-}
-
-inline const CPDF_Stream* ToStream(const CPDF_Object* obj) {
- return obj ? obj->AsStream() : nullptr;
-}
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_OBJECT_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp b/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp
deleted file mode 100644
index 9b702099bb..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp
+++ /dev/null
@@ -1,835 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_boolean.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_name.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_null.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_number.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_string.h"
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h"
-#include "core/fxcrt/fx_basic.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-using ScopedArray = std::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Array>>;
-using ScopedDict =
- std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>>;
-
-void TestArrayAccessors(const CPDF_Array* arr,
- size_t index,
- const char* str_val,
- const char* const_str_val,
- int int_val,
- float float_val,
- CPDF_Array* arr_val,
- CPDF_Dictionary* dict_val,
- CPDF_Stream* stream_val) {
- EXPECT_STREQ(str_val, arr->GetStringAt(index).c_str());
- EXPECT_EQ(int_val, arr->GetIntegerAt(index));
- EXPECT_EQ(float_val, arr->GetNumberAt(index));
- EXPECT_EQ(float_val, arr->GetFloatAt(index));
- EXPECT_EQ(arr_val, arr->GetArrayAt(index));
- EXPECT_EQ(dict_val, arr->GetDictAt(index));
- EXPECT_EQ(stream_val, arr->GetStreamAt(index));
-}
-
-} // namespace
-
-class PDFObjectsTest : public testing::Test {
- public:
- void SetUp() override {
- // Initialize different kinds of objects.
- // Boolean objects.
- CPDF_Boolean* boolean_false_obj = new CPDF_Boolean(false);
- CPDF_Boolean* boolean_true_obj = new CPDF_Boolean(true);
- // Number objects.
- CPDF_Number* number_int_obj = new CPDF_Number(1245);
- CPDF_Number* number_float_obj = new CPDF_Number(9.00345f);
- // String objects.
- CPDF_String* str_reg_obj = new CPDF_String(L"A simple test");
- CPDF_String* str_spec_obj = new CPDF_String(L"\t\n");
- // Name object.
- CPDF_Name* name_obj = new CPDF_Name("space");
- // Array object.
- m_ArrayObj = new CPDF_Array;
- m_ArrayObj->InsertAt(0, new CPDF_Number(8902));
- m_ArrayObj->InsertAt(1, new CPDF_Name("address"));
- // Dictionary object.
- m_DictObj = new CPDF_Dictionary();
- m_DictObj->SetFor("bool", new CPDF_Boolean(false));
- m_DictObj->SetFor("num", new CPDF_Number(0.23f));
- // Stream object.
- const char content[] = "abcdefghijklmnopqrstuvwxyz";
- size_t buf_len = FX_ArraySize(content);
- uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_len));
- memcpy(buf, content, buf_len);
- m_StreamDictObj = new CPDF_Dictionary();
- m_StreamDictObj->SetFor("key1", new CPDF_String(L" test dict"));
- m_StreamDictObj->SetFor("key2", new CPDF_Number(-1));
- CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj);
- // Null Object.
- CPDF_Null* null_obj = new CPDF_Null;
- // All direct objects.
- CPDF_Object* objs[] = {boolean_false_obj, boolean_true_obj, number_int_obj,
- number_float_obj, str_reg_obj, str_spec_obj,
- name_obj, m_ArrayObj, m_DictObj,
- stream_obj, null_obj};
- m_DirectObjTypes = {
- CPDF_Object::BOOLEAN, CPDF_Object::BOOLEAN, CPDF_Object::NUMBER,
- CPDF_Object::NUMBER, CPDF_Object::STRING, CPDF_Object::STRING,
- CPDF_Object::NAME, CPDF_Object::ARRAY, CPDF_Object::DICTIONARY,
- CPDF_Object::STREAM, CPDF_Object::NULLOBJ};
- for (size_t i = 0; i < FX_ArraySize(objs); ++i)
- m_DirectObjs.emplace_back(objs[i]);
-
- // Indirect references to indirect objects.
- m_ObjHolder.reset(new CPDF_IndirectObjectHolder());
- m_IndirectObjs = {boolean_true_obj, number_int_obj, str_spec_obj, name_obj,
- m_ArrayObj, m_DictObj, stream_obj};
- for (size_t i = 0; i < m_IndirectObjs.size(); ++i) {
- m_ObjHolder->AddIndirectObject(m_IndirectObjs[i]);
- m_RefObjs.emplace_back(new CPDF_Reference(
- m_ObjHolder.get(), m_IndirectObjs[i]->GetObjNum()));
- }
- }
-
- bool Equal(CPDF_Object* obj1, CPDF_Object* obj2) {
- if (obj1 == obj2)
- return true;
- if (!obj1 || !obj2 || obj1->GetType() != obj2->GetType())
- return false;
- switch (obj1->GetType()) {
- case CPDF_Object::BOOLEAN:
- return obj1->GetInteger() == obj2->GetInteger();
- case CPDF_Object::NUMBER:
- return obj1->AsNumber()->IsInteger() == obj2->AsNumber()->IsInteger() &&
- obj1->GetInteger() == obj2->GetInteger();
- case CPDF_Object::STRING:
- case CPDF_Object::NAME:
- return obj1->GetString() == obj2->GetString();
- case CPDF_Object::ARRAY: {
- const CPDF_Array* array1 = obj1->AsArray();
- const CPDF_Array* array2 = obj2->AsArray();
- if (array1->GetCount() != array2->GetCount())
- return false;
- for (size_t i = 0; i < array1->GetCount(); ++i) {
- if (!Equal(array1->GetObjectAt(i), array2->GetObjectAt(i)))
- return false;
- }
- return true;
- }
- case CPDF_Object::DICTIONARY: {
- const CPDF_Dictionary* dict1 = obj1->AsDictionary();
- const CPDF_Dictionary* dict2 = obj2->AsDictionary();
- if (dict1->GetCount() != dict2->GetCount())
- return false;
- for (CPDF_Dictionary::const_iterator it = dict1->begin();
- it != dict1->end(); ++it) {
- if (!Equal(it->second, dict2->GetObjectFor(it->first)))
- return false;
- }
- return true;
- }
- case CPDF_Object::NULLOBJ:
- return true;
- case CPDF_Object::STREAM: {
- const CPDF_Stream* stream1 = obj1->AsStream();
- const CPDF_Stream* stream2 = obj2->AsStream();
- if (!stream1->GetDict() && !stream2->GetDict())
- return true;
- // Compare dictionaries.
- if (!Equal(stream1->GetDict(), stream2->GetDict()))
- return false;
- // Compare sizes.
- if (stream1->GetRawSize() != stream2->GetRawSize())
- return false;
- // Compare contents.
- // Since this function is used for testing Clone(), only memory based
- // streams need to be handled.
- if (!stream1->IsMemoryBased() || !stream2->IsMemoryBased())
- return false;
- return FXSYS_memcmp(stream1->GetRawData(), stream2->GetRawData(),
- stream1->GetRawSize()) == 0;
- }
- case CPDF_Object::REFERENCE:
- return obj1->AsReference()->GetRefObjNum() ==
- obj2->AsReference()->GetRefObjNum();
- }
- return false;
- }
-
- protected:
- using ScopedObj = std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>>;
-
- // m_ObjHolder needs to be declared first and destructed last since it also
- // refers to some objects in m_DirectObjs.
- std::unique_ptr<CPDF_IndirectObjectHolder> m_ObjHolder;
- std::vector<ScopedObj> m_DirectObjs;
- std::vector<int> m_DirectObjTypes;
- std::vector<ScopedObj> m_RefObjs;
- CPDF_Dictionary* m_DictObj;
- CPDF_Dictionary* m_StreamDictObj;
- CPDF_Array* m_ArrayObj;
- std::vector<CPDF_Object*> m_IndirectObjs;
-};
-
-TEST_F(PDFObjectsTest, GetString) {
- const char* const direct_obj_results[] = {
- "false", "true", "1245", "9.00345", "A simple test", "\t\n", "space",
- "", "", "", ""};
- // Check for direct objects.
- for (size_t i = 0; i < m_DirectObjs.size(); ++i)
- EXPECT_STREQ(direct_obj_results[i], m_DirectObjs[i]->GetString().c_str());
-
- // Check indirect references.
- const char* const indirect_obj_results[] = {"true", "1245", "\t\n", "space",
- "", "", ""};
- for (size_t i = 0; i < m_RefObjs.size(); ++i) {
- EXPECT_STREQ(indirect_obj_results[i], m_RefObjs[i]->GetString().c_str());
- }
-}
-
-TEST_F(PDFObjectsTest, GetUnicodeText) {
- const wchar_t* const direct_obj_results[] = {
- L"", L"", L"", L"", L"A simple test",
- L"\t\n", L"space", L"", L"", L"abcdefghijklmnopqrstuvwxyz",
- L""};
- // Check for direct objects.
- for (size_t i = 0; i < m_DirectObjs.size(); ++i) {
- EXPECT_STREQ(direct_obj_results[i],
- m_DirectObjs[i]->GetUnicodeText().c_str());
- }
-
- // Check indirect references.
- for (const auto& it : m_RefObjs)
- EXPECT_STREQ(L"", it->GetUnicodeText().c_str());
-}
-
-TEST_F(PDFObjectsTest, GetNumber) {
- const FX_FLOAT direct_obj_results[] = {0, 0, 1245, 9.00345f, 0, 0,
- 0, 0, 0, 0, 0};
- // Check for direct objects.
- for (size_t i = 0; i < m_DirectObjs.size(); ++i)
- EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->GetNumber());
-
- // Check indirect references.
- const FX_FLOAT indirect_obj_results[] = {0, 1245, 0, 0, 0, 0, 0};
- for (size_t i = 0; i < m_RefObjs.size(); ++i)
- EXPECT_EQ(indirect_obj_results[i], m_RefObjs[i]->GetNumber());
-}
-
-TEST_F(PDFObjectsTest, GetInteger) {
- const int direct_obj_results[] = {0, 1, 1245, 9, 0, 0, 0, 0, 0, 0, 0};
- // Check for direct objects.
- for (size_t i = 0; i < m_DirectObjs.size(); ++i)
- EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->GetInteger());
-
- // Check indirect references.
- const int indirect_obj_results[] = {1, 1245, 0, 0, 0, 0, 0};
- for (size_t i = 0; i < m_RefObjs.size(); ++i)
- EXPECT_EQ(indirect_obj_results[i], m_RefObjs[i]->GetInteger());
-}
-
-TEST_F(PDFObjectsTest, GetDict) {
- const CPDF_Dictionary* const direct_obj_results[] = {
- nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr, m_DictObj, m_StreamDictObj, nullptr};
- // Check for direct objects.
- for (size_t i = 0; i < m_DirectObjs.size(); ++i)
- EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->GetDict());
-
- // Check indirect references.
- const CPDF_Dictionary* const indirect_obj_results[] = {
- nullptr, nullptr, nullptr, nullptr, nullptr, m_DictObj, m_StreamDictObj};
- for (size_t i = 0; i < m_RefObjs.size(); ++i)
- EXPECT_EQ(indirect_obj_results[i], m_RefObjs[i]->GetDict());
-}
-
-TEST_F(PDFObjectsTest, GetArray) {
- const CPDF_Array* const direct_obj_results[] = {
- nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- nullptr, m_ArrayObj, nullptr, nullptr, nullptr};
- // Check for direct objects.
- for (size_t i = 0; i < m_DirectObjs.size(); ++i)
- EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->AsArray());
-
- // Check indirect references.
- for (const auto& it : m_RefObjs)
- EXPECT_EQ(nullptr, it->AsArray());
-}
-
-TEST_F(PDFObjectsTest, Clone) {
- // Check for direct objects.
- for (size_t i = 0; i < m_DirectObjs.size(); ++i) {
- ScopedObj obj(m_DirectObjs[i]->Clone());
- EXPECT_TRUE(Equal(m_DirectObjs[i].get(), obj.get()));
- }
-
- // Check indirect references.
- for (const auto& it : m_RefObjs) {
- ScopedObj obj(it->Clone());
- EXPECT_TRUE(Equal(it.get(), obj.get()));
- }
-}
-
-TEST_F(PDFObjectsTest, GetType) {
- // Check for direct objects.
- for (size_t i = 0; i < m_DirectObjs.size(); ++i)
- EXPECT_EQ(m_DirectObjTypes[i], m_DirectObjs[i]->GetType());
-
- // Check indirect references.
- for (const auto& it : m_RefObjs)
- EXPECT_EQ(CPDF_Object::REFERENCE, it->GetType());
-}
-
-TEST_F(PDFObjectsTest, GetDirect) {
- // Check for direct objects.
- for (size_t i = 0; i < m_DirectObjs.size(); ++i)
- EXPECT_EQ(m_DirectObjs[i].get(), m_DirectObjs[i]->GetDirect());
-
- // Check indirect references.
- for (size_t i = 0; i < m_RefObjs.size(); ++i)
- EXPECT_EQ(m_IndirectObjs[i], m_RefObjs[i]->GetDirect());
-}
-
-TEST_F(PDFObjectsTest, SetString) {
- // Check for direct objects.
- const char* const set_values[] = {"true", "fake", "3.125f", "097",
- "changed", "", "NewName"};
- const char* const expected[] = {"true", "false", "3.125", "97",
- "changed", "", "NewName"};
- for (size_t i = 0; i < FX_ArraySize(set_values); ++i) {
- m_DirectObjs[i]->SetString(set_values[i]);
- EXPECT_STREQ(expected[i], m_DirectObjs[i]->GetString().c_str());
- }
-}
-
-TEST_F(PDFObjectsTest, IsTypeAndAsType) {
- // Check for direct objects.
- for (size_t i = 0; i < m_DirectObjs.size(); ++i) {
- if (m_DirectObjTypes[i] == CPDF_Object::ARRAY) {
- EXPECT_TRUE(m_DirectObjs[i]->IsArray());
- EXPECT_EQ(m_DirectObjs[i].get(), m_DirectObjs[i]->AsArray());
- } else {
- EXPECT_FALSE(m_DirectObjs[i]->IsArray());
- EXPECT_EQ(nullptr, m_DirectObjs[i]->AsArray());
- }
-
- if (m_DirectObjTypes[i] == CPDF_Object::BOOLEAN) {
- EXPECT_TRUE(m_DirectObjs[i]->IsBoolean());
- EXPECT_EQ(m_DirectObjs[i].get(), m_DirectObjs[i]->AsBoolean());
- } else {
- EXPECT_FALSE(m_DirectObjs[i]->IsBoolean());
- EXPECT_EQ(nullptr, m_DirectObjs[i]->AsBoolean());
- }
-
- if (m_DirectObjTypes[i] == CPDF_Object::NAME) {
- EXPECT_TRUE(m_DirectObjs[i]->IsName());
- EXPECT_EQ(m_DirectObjs[i].get(), m_DirectObjs[i]->AsName());
- } else {
- EXPECT_FALSE(m_DirectObjs[i]->IsName());
- EXPECT_EQ(nullptr, m_DirectObjs[i]->AsName());
- }
-
- if (m_DirectObjTypes[i] == CPDF_Object::NUMBER) {
- EXPECT_TRUE(m_DirectObjs[i]->IsNumber());
- EXPECT_EQ(m_DirectObjs[i].get(), m_DirectObjs[i]->AsNumber());
- } else {
- EXPECT_FALSE(m_DirectObjs[i]->IsNumber());
- EXPECT_EQ(nullptr, m_DirectObjs[i]->AsNumber());
- }
-
- if (m_DirectObjTypes[i] == CPDF_Object::STRING) {
- EXPECT_TRUE(m_DirectObjs[i]->IsString());
- EXPECT_EQ(m_DirectObjs[i].get(), m_DirectObjs[i]->AsString());
- } else {
- EXPECT_FALSE(m_DirectObjs[i]->IsString());
- EXPECT_EQ(nullptr, m_DirectObjs[i]->AsString());
- }
-
- if (m_DirectObjTypes[i] == CPDF_Object::DICTIONARY) {
- EXPECT_TRUE(m_DirectObjs[i]->IsDictionary());
- EXPECT_EQ(m_DirectObjs[i].get(), m_DirectObjs[i]->AsDictionary());
- } else {
- EXPECT_FALSE(m_DirectObjs[i]->IsDictionary());
- EXPECT_EQ(nullptr, m_DirectObjs[i]->AsDictionary());
- }
-
- if (m_DirectObjTypes[i] == CPDF_Object::STREAM) {
- EXPECT_TRUE(m_DirectObjs[i]->IsStream());
- EXPECT_EQ(m_DirectObjs[i].get(), m_DirectObjs[i]->AsStream());
- } else {
- EXPECT_FALSE(m_DirectObjs[i]->IsStream());
- EXPECT_EQ(nullptr, m_DirectObjs[i]->AsStream());
- }
-
- EXPECT_FALSE(m_DirectObjs[i]->IsReference());
- EXPECT_EQ(nullptr, m_DirectObjs[i]->AsReference());
- }
- // Check indirect references.
- for (size_t i = 0; i < m_RefObjs.size(); ++i) {
- EXPECT_TRUE(m_RefObjs[i]->IsReference());
- EXPECT_EQ(m_RefObjs[i].get(), m_RefObjs[i]->AsReference());
- }
-}
-
-TEST(PDFArrayTest, GetMatrix) {
- float elems[][6] = {{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
- {1, 2, 3, 4, 5, 6},
- {2.3f, 4.05f, 3, -2, -3, 0.0f},
- {0.05f, 0.1f, 0.56f, 0.67f, 1.34f, 99.9f}};
- for (size_t i = 0; i < FX_ArraySize(elems); ++i) {
- ScopedArray arr(new CPDF_Array);
- CFX_Matrix matrix(elems[i][0], elems[i][1], elems[i][2], elems[i][3],
- elems[i][4], elems[i][5]);
- for (size_t j = 0; j < 6; ++j)
- arr->AddNumber(elems[i][j]);
- CFX_Matrix arr_matrix = arr->GetMatrix();
- EXPECT_EQ(matrix.GetA(), arr_matrix.GetA());
- EXPECT_EQ(matrix.GetB(), arr_matrix.GetB());
- EXPECT_EQ(matrix.GetC(), arr_matrix.GetC());
- EXPECT_EQ(matrix.GetD(), arr_matrix.GetD());
- EXPECT_EQ(matrix.GetE(), arr_matrix.GetE());
- EXPECT_EQ(matrix.GetF(), arr_matrix.GetF());
- }
-}
-
-TEST(PDFArrayTest, GetRect) {
- float elems[][4] = {{0.0f, 0.0f, 0.0f, 0.0f},
- {1, 2, 5, 6},
- {2.3f, 4.05f, -3, 0.0f},
- {0.05f, 0.1f, 1.34f, 99.9f}};
- for (size_t i = 0; i < FX_ArraySize(elems); ++i) {
- ScopedArray arr(new CPDF_Array);
- CFX_FloatRect rect(elems[i]);
- for (size_t j = 0; j < 4; ++j)
- arr->AddNumber(elems[i][j]);
- CFX_FloatRect arr_rect = arr->GetRect();
- EXPECT_EQ(rect.left, arr_rect.left);
- EXPECT_EQ(rect.right, arr_rect.right);
- EXPECT_EQ(rect.bottom, arr_rect.bottom);
- EXPECT_EQ(rect.top, arr_rect.top);
- }
-}
-
-TEST(PDFArrayTest, GetTypeAt) {
- {
- // Boolean array.
- const bool vals[] = {true, false, false, true, true};
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(vals); ++i)
- arr->InsertAt(i, new CPDF_Boolean(vals[i]));
- for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
- TestArrayAccessors(arr.get(), i, // Array and index.
- vals[i] ? "true" : "false", // String value.
- nullptr, // Const string value.
- vals[i] ? 1 : 0, // Integer value.
- 0, // Float value.
- nullptr, // Array value.
- nullptr, // Dictionary value.
- nullptr); // Stream value.
- }
- }
- {
- // Integer array.
- const int vals[] = {10, 0, -345, 2089345456, -1000000000, 567, 93658767};
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(vals); ++i)
- arr->InsertAt(i, new CPDF_Number(vals[i]));
- for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
- char buf[33];
- TestArrayAccessors(arr.get(), i, // Array and index.
- FXSYS_itoa(vals[i], buf, 10), // String value.
- nullptr, // Const string value.
- vals[i], // Integer value.
- vals[i], // Float value.
- nullptr, // Array value.
- nullptr, // Dictionary value.
- nullptr); // Stream value.
- }
- }
- {
- // Float array.
- const float vals[] = {0.0f, 0, 10, 10.0f, 0.0345f,
- 897.34f, -2.5f, -1.0f, -345.0f, -0.0f};
- const char* const expected_str[] = {
- "0", "0", "10", "10", "0.0345", "897.34", "-2.5", "-1", "-345", "0"};
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
- arr->InsertAt(i, new CPDF_Number(vals[i]));
- }
- for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
- TestArrayAccessors(arr.get(), i, // Array and index.
- expected_str[i], // String value.
- nullptr, // Const string value.
- vals[i], // Integer value.
- vals[i], // Float value.
- nullptr, // Array value.
- nullptr, // Dictionary value.
- nullptr); // Stream value.
- }
- }
- {
- // String and name array
- const char* const vals[] = {"this", "adsde$%^", "\r\t", "\"012",
- ".", "EYREW", "It is a joke :)"};
- ScopedArray string_array(new CPDF_Array);
- ScopedArray name_array(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
- string_array->InsertAt(i, new CPDF_String(vals[i], false));
- name_array->InsertAt(i, new CPDF_Name(vals[i]));
- }
- for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
- TestArrayAccessors(string_array.get(), i, // Array and index.
- vals[i], // String value.
- vals[i], // Const string value.
- 0, // Integer value.
- 0, // Float value.
- nullptr, // Array value.
- nullptr, // Dictionary value.
- nullptr); // Stream value.
- TestArrayAccessors(name_array.get(), i, // Array and index.
- vals[i], // String value.
- vals[i], // Const string value.
- 0, // Integer value.
- 0, // Float value.
- nullptr, // Array value.
- nullptr, // Dictionary value.
- nullptr); // Stream value.
- }
- }
- {
- // Null element array.
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < 3; ++i)
- arr->InsertAt(i, new CPDF_Null);
- for (size_t i = 0; i < 3; ++i) {
- TestArrayAccessors(arr.get(), i, // Array and index.
- "", // String value.
- nullptr, // Const string value.
- 0, // Integer value.
- 0, // Float value.
- nullptr, // Array value.
- nullptr, // Dictionary value.
- nullptr); // Stream value.
- }
- }
- {
- // Array of array.
- CPDF_Array* vals[3];
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < 3; ++i) {
- vals[i] = new CPDF_Array;
- for (size_t j = 0; j < 3; ++j) {
- int value = j + 100;
- vals[i]->InsertAt(i, new CPDF_Number(value));
- }
- arr->InsertAt(i, vals[i]);
- }
- for (size_t i = 0; i < 3; ++i) {
- TestArrayAccessors(arr.get(), i, // Array and index.
- "", // String value.
- nullptr, // Const string value.
- 0, // Integer value.
- 0, // Float value.
- vals[i], // Array value.
- nullptr, // Dictionary value.
- nullptr); // Stream value.
- }
- }
- {
- // Dictionary array.
- CPDF_Dictionary* vals[3];
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < 3; ++i) {
- vals[i] = new CPDF_Dictionary();
- for (size_t j = 0; j < 3; ++j) {
- std::string key("key");
- char buf[33];
- key.append(FXSYS_itoa(j, buf, 10));
- int value = j + 200;
- vals[i]->SetFor(key.c_str(), new CPDF_Number(value));
- }
- arr->InsertAt(i, vals[i]);
- }
- for (size_t i = 0; i < 3; ++i) {
- TestArrayAccessors(arr.get(), i, // Array and index.
- "", // String value.
- nullptr, // Const string value.
- 0, // Integer value.
- 0, // Float value.
- nullptr, // Array value.
- vals[i], // Dictionary value.
- nullptr); // Stream value.
- }
- }
- {
- // Stream array.
- CPDF_Dictionary* vals[3];
- CPDF_Stream* stream_vals[3];
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < 3; ++i) {
- vals[i] = new CPDF_Dictionary();
- for (size_t j = 0; j < 3; ++j) {
- std::string key("key");
- char buf[33];
- key.append(FXSYS_itoa(j, buf, 10));
- int value = j + 200;
- vals[i]->SetFor(key.c_str(), new CPDF_Number(value));
- }
- uint8_t content[] = "content: this is a stream";
- size_t data_size = FX_ArraySize(content);
- uint8_t* data = reinterpret_cast<uint8_t*>(malloc(data_size));
- memcpy(data, content, data_size);
- stream_vals[i] = new CPDF_Stream(data, data_size, vals[i]);
- arr->InsertAt(i, stream_vals[i]);
- }
- for (size_t i = 0; i < 3; ++i) {
- TestArrayAccessors(arr.get(), i, // Array and index.
- "", // String value.
- nullptr, // Const string value.
- 0, // Integer value.
- 0, // Float value.
- nullptr, // Array value.
- vals[i], // Dictionary value.
- stream_vals[i]); // Stream value.
- }
- }
- {
- // Mixed array.
- ScopedArray arr(new CPDF_Array);
- // Array arr will take ownership of all the objects inserted.
- arr->InsertAt(0, new CPDF_Boolean(true));
- arr->InsertAt(1, new CPDF_Boolean(false));
- arr->InsertAt(2, new CPDF_Number(0));
- arr->InsertAt(3, new CPDF_Number(-1234));
- arr->InsertAt(4, new CPDF_Number(2345.0f));
- arr->InsertAt(5, new CPDF_Number(0.05f));
- arr->InsertAt(6, new CPDF_String("", false));
- arr->InsertAt(7, new CPDF_String("It is a test!", false));
- arr->InsertAt(8, new CPDF_Name("NAME"));
- arr->InsertAt(9, new CPDF_Name("test"));
- arr->InsertAt(10, new CPDF_Null());
- CPDF_Array* arr_val = new CPDF_Array;
- arr_val->AddNumber(1);
- arr_val->AddNumber(2);
- arr->InsertAt(11, arr_val);
- CPDF_Dictionary* dict_val = new CPDF_Dictionary();
- dict_val->SetFor("key1", new CPDF_String("Linda", false));
- dict_val->SetFor("key2", new CPDF_String("Zoe", false));
- arr->InsertAt(12, dict_val);
- CPDF_Dictionary* stream_dict = new CPDF_Dictionary();
- stream_dict->SetFor("key1", new CPDF_String("John", false));
- stream_dict->SetFor("key2", new CPDF_String("King", false));
- uint8_t data[] = "A stream for test";
- // The data buffer will be owned by stream object, so it needs to be
- // dynamically allocated.
- size_t buf_size = sizeof(data);
- uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_size));
- memcpy(buf, data, buf_size);
- CPDF_Stream* stream_val = new CPDF_Stream(buf, buf_size, stream_dict);
- arr->InsertAt(13, stream_val);
- const char* const expected_str[] = {
- "true", "false", "0", "-1234", "2345", "0.05", "",
- "It is a test!", "NAME", "test", "", "", "", ""};
- const int expected_int[] = {1, 0, 0, -1234, 2345, 0, 0,
- 0, 0, 0, 0, 0, 0, 0};
- const float expected_float[] = {0, 0, 0, -1234, 2345, 0.05f, 0,
- 0, 0, 0, 0, 0, 0, 0};
- for (size_t i = 0; i < arr->GetCount(); ++i) {
- EXPECT_STREQ(expected_str[i], arr->GetStringAt(i).c_str());
- EXPECT_EQ(expected_int[i], arr->GetIntegerAt(i));
- EXPECT_EQ(expected_float[i], arr->GetNumberAt(i));
- EXPECT_EQ(expected_float[i], arr->GetFloatAt(i));
- if (i == 11)
- EXPECT_EQ(arr_val, arr->GetArrayAt(i));
- else
- EXPECT_EQ(nullptr, arr->GetArrayAt(i));
- if (i == 13) {
- EXPECT_EQ(stream_dict, arr->GetDictAt(i));
- EXPECT_EQ(stream_val, arr->GetStreamAt(i));
- } else {
- EXPECT_EQ(nullptr, arr->GetStreamAt(i));
- if (i == 12)
- EXPECT_EQ(dict_val, arr->GetDictAt(i));
- else
- EXPECT_EQ(nullptr, arr->GetDictAt(i));
- }
- }
- }
-}
-
-TEST(PDFArrayTest, AddNumber) {
- float vals[] = {1.0f, -1.0f, 0, 0.456734f,
- 12345.54321f, 0.5f, 1000, 0.000045f};
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(vals); ++i)
- arr->AddNumber(vals[i]);
- for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
- EXPECT_EQ(CPDF_Object::NUMBER, arr->GetObjectAt(i)->GetType());
- EXPECT_EQ(vals[i], arr->GetObjectAt(i)->GetNumber());
- }
-}
-
-TEST(PDFArrayTest, AddInteger) {
- int vals[] = {0, 1, 934435456, 876, 10000, -1, -24354656, -100};
- ScopedArray arr(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(vals); ++i)
- arr->AddInteger(vals[i]);
- for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
- EXPECT_EQ(CPDF_Object::NUMBER, arr->GetObjectAt(i)->GetType());
- EXPECT_EQ(vals[i], arr->GetObjectAt(i)->GetNumber());
- }
-}
-
-TEST(PDFArrayTest, AddStringAndName) {
- const char* vals[] = {"", "a", "ehjhRIOYTTFdfcdnv", "122323",
- "$#%^&**", " ", "This is a test.\r\n"};
- ScopedArray string_array(new CPDF_Array);
- ScopedArray name_array(new CPDF_Array);
- for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
- string_array->AddString(vals[i]);
- name_array->AddName(vals[i]);
- }
- for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
- EXPECT_EQ(CPDF_Object::STRING, string_array->GetObjectAt(i)->GetType());
- EXPECT_STREQ(vals[i], string_array->GetObjectAt(i)->GetString().c_str());
- EXPECT_EQ(CPDF_Object::NAME, name_array->GetObjectAt(i)->GetType());
- EXPECT_STREQ(vals[i], name_array->GetObjectAt(i)->GetString().c_str());
- }
-}
-
-TEST(PDFArrayTest, AddReferenceAndGetObjectAt) {
- std::unique_ptr<CPDF_IndirectObjectHolder> holder(
- new CPDF_IndirectObjectHolder());
- CPDF_Boolean* boolean_obj = new CPDF_Boolean(true);
- CPDF_Number* int_obj = new CPDF_Number(-1234);
- CPDF_Number* float_obj = new CPDF_Number(2345.089f);
- CPDF_String* str_obj = new CPDF_String("Adsfdsf 343434 %&&*\n", false);
- CPDF_Name* name_obj = new CPDF_Name("Title:");
- CPDF_Null* null_obj = new CPDF_Null();
- CPDF_Object* indirect_objs[] = {boolean_obj, int_obj, float_obj,
- str_obj, name_obj, null_obj};
- unsigned int obj_nums[] = {2, 4, 7, 2345, 799887, 1};
- ScopedArray arr(new CPDF_Array);
- ScopedArray arr1(new CPDF_Array);
- // Create two arrays of references by different AddReference() APIs.
- for (size_t i = 0; i < FX_ArraySize(indirect_objs); ++i) {
- // All the indirect objects inserted will be owned by holder.
- holder->ReplaceIndirectObjectIfHigherGeneration(obj_nums[i],
- indirect_objs[i]);
- arr->AddReference(holder.get(), obj_nums[i]);
- arr1->AddReference(holder.get(), indirect_objs[i]->GetObjNum());
- }
- // Check indirect objects.
- for (size_t i = 0; i < FX_ArraySize(obj_nums); ++i)
- EXPECT_EQ(indirect_objs[i], holder->GetOrParseIndirectObject(obj_nums[i]));
- // Check arrays.
- EXPECT_EQ(arr->GetCount(), arr1->GetCount());
- for (size_t i = 0; i < arr->GetCount(); ++i) {
- EXPECT_EQ(CPDF_Object::REFERENCE, arr->GetObjectAt(i)->GetType());
- EXPECT_EQ(indirect_objs[i], arr->GetObjectAt(i)->GetDirect());
- EXPECT_EQ(indirect_objs[i], arr->GetDirectObjectAt(i));
- EXPECT_EQ(CPDF_Object::REFERENCE, arr1->GetObjectAt(i)->GetType());
- EXPECT_EQ(indirect_objs[i], arr1->GetObjectAt(i)->GetDirect());
- EXPECT_EQ(indirect_objs[i], arr1->GetDirectObjectAt(i));
- }
-}
-
-TEST(PDFArrayTest, CloneDirectObject) {
- CPDF_IndirectObjectHolder objects_holder;
- ScopedArray array(new CPDF_Array);
- array->AddReference(&objects_holder, 1234);
- ASSERT_EQ(1U, array->GetCount());
- CPDF_Object* obj = array->GetObjectAt(0);
- ASSERT_TRUE(obj);
- EXPECT_TRUE(obj->IsReference());
-
- CPDF_Object* cloned_array_object = array->CloneDirectObject();
- ASSERT_TRUE(cloned_array_object);
- ASSERT_TRUE(cloned_array_object->IsArray());
-
- ScopedArray cloned_array(cloned_array_object->AsArray());
- ASSERT_EQ(1U, cloned_array->GetCount());
- CPDF_Object* cloned_obj = cloned_array->GetObjectAt(0);
- EXPECT_FALSE(cloned_obj);
-}
-
-TEST(PDFDictionaryTest, CloneDirectObject) {
- CPDF_IndirectObjectHolder objects_holder;
- ScopedDict dict(new CPDF_Dictionary());
- dict->SetReferenceFor("foo", &objects_holder, 1234);
- ASSERT_EQ(1U, dict->GetCount());
- CPDF_Object* obj = dict->GetObjectFor("foo");
- ASSERT_TRUE(obj);
- EXPECT_TRUE(obj->IsReference());
-
- CPDF_Object* cloned_dict_object = dict->CloneDirectObject();
- ASSERT_TRUE(cloned_dict_object);
- ASSERT_TRUE(cloned_dict_object->IsDictionary());
-
- ScopedDict cloned_dict(cloned_dict_object->AsDictionary());
- ASSERT_EQ(1U, cloned_dict->GetCount());
- CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo");
- EXPECT_FALSE(cloned_obj);
-}
-
-TEST(PDFObjectTest, CloneCheckLoop) {
- {
- // Create an object with a reference loop.
- ScopedArray arr_obj(new CPDF_Array);
- // Dictionary object.
- CPDF_Dictionary* dict_obj = new CPDF_Dictionary();
- dict_obj->SetFor("arr", arr_obj.get());
- arr_obj->InsertAt(0, dict_obj);
-
- // Clone this object to see whether stack overflow will be triggered.
- ScopedArray cloned_array(arr_obj->Clone()->AsArray());
- // Cloned object should be the same as the original.
- ASSERT_TRUE(cloned_array);
- EXPECT_EQ(1u, cloned_array->GetCount());
- CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0);
- ASSERT_TRUE(cloned_dict);
- ASSERT_TRUE(cloned_dict->IsDictionary());
- // Recursively referenced object is not cloned.
- EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr"));
- }
- {
- CPDF_IndirectObjectHolder objects_holder;
- // Create an object with a reference loop.
- CPDF_Dictionary* dict_obj = new CPDF_Dictionary();
- CPDF_Array* arr_obj = new CPDF_Array;
- objects_holder.AddIndirectObject(dict_obj);
- EXPECT_EQ(1u, dict_obj->GetObjNum());
- dict_obj->SetFor("arr", arr_obj);
- arr_obj->InsertAt(
- 0, new CPDF_Reference(&objects_holder, dict_obj->GetObjNum()));
- CPDF_Object* elem0 = arr_obj->GetObjectAt(0);
- ASSERT_TRUE(elem0);
- ASSERT_TRUE(elem0->IsReference());
- EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum());
- EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect());
-
- // Clone this object to see whether stack overflow will be triggered.
- ScopedDict cloned_dict(ToDictionary(dict_obj->CloneDirectObject()));
- // Cloned object should be the same as the original.
- ASSERT_TRUE(cloned_dict);
- CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr");
- ASSERT_TRUE(cloned_arr);
- ASSERT_TRUE(cloned_arr->IsArray());
- EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount());
- // Recursively referenced object is not cloned.
- EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0));
- }
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_parser.cpp b/core/fpdfapi/fpdf_parser/cpdf_parser.cpp
deleted file mode 100644
index 182d3869bc..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_parser.cpp
+++ /dev/null
@@ -1,1637 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_parser.h"
-
-#include <vector>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_crypto_handler.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_document.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_number.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_security_handler.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h"
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h"
-#include "core/fxcrt/fx_ext.h"
-#include "core/fxcrt/fx_safe_types.h"
-#include "third_party/base/stl_util.h"
-
-namespace {
-
-// A limit on the size of the xref table. Theoretical limits are higher, but
-// this may be large enough in practice.
-const int32_t kMaxXRefSize = 1048576;
-
-uint32_t GetVarInt(const uint8_t* p, int32_t n) {
- uint32_t result = 0;
- for (int32_t i = 0; i < n; ++i)
- result = result * 256 + p[i];
- return result;
-}
-
-int32_t GetStreamNCount(CPDF_StreamAcc* pObjStream) {
- return pObjStream->GetDict()->GetIntegerFor("N");
-}
-
-int32_t GetStreamFirst(CPDF_StreamAcc* pObjStream) {
- return pObjStream->GetDict()->GetIntegerFor("First");
-}
-
-} // namespace
-
-CPDF_Parser::CPDF_Parser()
- : m_pDocument(nullptr),
- m_bHasParsed(false),
- m_bOwnFileRead(true),
- m_FileVersion(0),
- m_pTrailer(nullptr),
- m_pEncryptDict(nullptr),
- m_bVersionUpdated(false),
- m_pLinearized(nullptr),
- m_dwFirstPageNo(0),
- m_dwXrefStartObjNum(0) {
- m_pSyntax.reset(new CPDF_SyntaxParser);
-}
-
-CPDF_Parser::~CPDF_Parser() {
- if (m_pTrailer)
- m_pTrailer->Release();
-
- ReleaseEncryptHandler();
- SetEncryptDictionary(nullptr);
-
- if (m_bOwnFileRead && m_pSyntax->m_pFileAccess) {
- m_pSyntax->m_pFileAccess->Release();
- m_pSyntax->m_pFileAccess = nullptr;
- }
-
- int32_t iLen = m_Trailers.GetSize();
- for (int32_t i = 0; i < iLen; ++i) {
- if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i))
- trailer->Release();
- }
-
- if (m_pLinearized)
- m_pLinearized->Release();
-}
-
-uint32_t CPDF_Parser::GetLastObjNum() const {
- return m_ObjectInfo.empty() ? 0 : m_ObjectInfo.rbegin()->first;
-}
-
-bool CPDF_Parser::IsValidObjectNumber(uint32_t objnum) const {
- return !m_ObjectInfo.empty() && objnum <= m_ObjectInfo.rbegin()->first;
-}
-
-FX_FILESIZE CPDF_Parser::GetObjectPositionOrZero(uint32_t objnum) const {
- auto it = m_ObjectInfo.find(objnum);
- return it != m_ObjectInfo.end() ? it->second.pos : 0;
-}
-
-uint8_t CPDF_Parser::GetObjectType(uint32_t objnum) const {
- ASSERT(IsValidObjectNumber(objnum));
- auto it = m_ObjectInfo.find(objnum);
- return it != m_ObjectInfo.end() ? it->second.type : 0;
-}
-
-uint16_t CPDF_Parser::GetObjectGenNum(uint32_t objnum) const {
- ASSERT(IsValidObjectNumber(objnum));
- auto it = m_ObjectInfo.find(objnum);
- return it != m_ObjectInfo.end() ? it->second.gennum : 0;
-}
-
-bool CPDF_Parser::IsObjectFreeOrNull(uint32_t objnum) const {
- uint8_t type = GetObjectType(objnum);
- return type == 0 || type == 255;
-}
-
-void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict) {
- m_pEncryptDict = pDict;
-}
-
-CPDF_CryptoHandler* CPDF_Parser::GetCryptoHandler() {
- return m_pSyntax->m_pCryptoHandler.get();
-}
-
-IFX_FileRead* CPDF_Parser::GetFileAccess() const {
- return m_pSyntax->m_pFileAccess;
-}
-
-void CPDF_Parser::ShrinkObjectMap(uint32_t objnum) {
- if (objnum == 0) {
- m_ObjectInfo.clear();
- return;
- }
-
- auto it = m_ObjectInfo.lower_bound(objnum);
- while (it != m_ObjectInfo.end()) {
- auto saved_it = it++;
- m_ObjectInfo.erase(saved_it);
- }
-
- if (!pdfium::ContainsKey(m_ObjectInfo, objnum - 1))
- m_ObjectInfo[objnum - 1].pos = 0;
-}
-
-CPDF_Parser::Error CPDF_Parser::StartParse(IFX_FileRead* pFileAccess,
- CPDF_Document* pDocument) {
- ASSERT(!m_bHasParsed);
- m_bHasParsed = true;
-
- m_bXRefStream = FALSE;
- m_LastXRefOffset = 0;
- m_bOwnFileRead = true;
-
- int32_t offset = GetHeaderOffset(pFileAccess);
- if (offset == -1) {
- if (pFileAccess)
- pFileAccess->Release();
- return FORMAT_ERROR;
- }
- m_pSyntax->InitParser(pFileAccess, offset);
-
- uint8_t ch;
- if (!m_pSyntax->GetCharAt(5, ch))
- return FORMAT_ERROR;
- if (std::isdigit(ch))
- m_FileVersion = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)) * 10;
-
- if (!m_pSyntax->GetCharAt(7, ch))
- return FORMAT_ERROR;
- if (std::isdigit(ch))
- m_FileVersion += FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch));
-
- if (m_pSyntax->m_FileLen < m_pSyntax->m_HeaderOffset + 9)
- return FORMAT_ERROR;
-
- m_pSyntax->RestorePos(m_pSyntax->m_FileLen - m_pSyntax->m_HeaderOffset - 9);
- m_pDocument = pDocument;
-
- FX_BOOL bXRefRebuilt = FALSE;
- if (m_pSyntax->SearchWord("startxref", TRUE, FALSE, 4096)) {
- m_SortedOffset.insert(m_pSyntax->SavePos());
- m_pSyntax->GetKeyword();
-
- bool bNumber;
- CFX_ByteString xrefpos_str = m_pSyntax->GetNextWord(&bNumber);
- if (!bNumber)
- return FORMAT_ERROR;
-
- m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str.c_str());
- if (!LoadAllCrossRefV4(m_LastXRefOffset) &&
- !LoadAllCrossRefV5(m_LastXRefOffset)) {
- if (!RebuildCrossRef())
- return FORMAT_ERROR;
-
- bXRefRebuilt = TRUE;
- m_LastXRefOffset = 0;
- }
- } else {
- if (!RebuildCrossRef())
- return FORMAT_ERROR;
-
- bXRefRebuilt = TRUE;
- }
- Error eRet = SetEncryptHandler();
- if (eRet != SUCCESS)
- return eRet;
-
- m_pDocument->LoadDoc();
- if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) {
- if (bXRefRebuilt)
- return FORMAT_ERROR;
-
- ReleaseEncryptHandler();
- if (!RebuildCrossRef())
- return FORMAT_ERROR;
-
- eRet = SetEncryptHandler();
- if (eRet != SUCCESS)
- return eRet;
-
- m_pDocument->LoadDoc();
- if (!m_pDocument->GetRoot())
- return FORMAT_ERROR;
- }
- if (GetRootObjNum() == 0) {
- ReleaseEncryptHandler();
- if (!RebuildCrossRef() || GetRootObjNum() == 0)
- return FORMAT_ERROR;
-
- eRet = SetEncryptHandler();
- if (eRet != SUCCESS)
- return eRet;
- }
- if (m_pSecurityHandler && !m_pSecurityHandler->IsMetadataEncrypted()) {
- CPDF_Reference* pMetadata =
- ToReference(m_pDocument->GetRoot()->GetObjectFor("Metadata"));
- if (pMetadata)
- m_pSyntax->m_MetadataObjnum = pMetadata->GetRefObjNum();
- }
- return SUCCESS;
-}
-CPDF_Parser::Error CPDF_Parser::SetEncryptHandler() {
- ReleaseEncryptHandler();
- SetEncryptDictionary(nullptr);
-
- if (!m_pTrailer)
- return FORMAT_ERROR;
-
- CPDF_Object* pEncryptObj = m_pTrailer->GetObjectFor("Encrypt");
- if (pEncryptObj) {
- if (CPDF_Dictionary* pEncryptDict = pEncryptObj->AsDictionary()) {
- SetEncryptDictionary(pEncryptDict);
- } else if (CPDF_Reference* pRef = pEncryptObj->AsReference()) {
- pEncryptObj = m_pDocument->GetOrParseIndirectObject(pRef->GetRefObjNum());
- if (pEncryptObj)
- SetEncryptDictionary(pEncryptObj->GetDict());
- }
- }
-
- if (m_pEncryptDict) {
- CFX_ByteString filter = m_pEncryptDict->GetStringFor("Filter");
- std::unique_ptr<CPDF_SecurityHandler> pSecurityHandler;
- Error err = HANDLER_ERROR;
- if (filter == "Standard") {
- pSecurityHandler.reset(new CPDF_SecurityHandler);
- err = PASSWORD_ERROR;
- }
- if (!pSecurityHandler)
- return HANDLER_ERROR;
-
- if (!pSecurityHandler->OnInit(this, m_pEncryptDict))
- return err;
-
- m_pSecurityHandler = std::move(pSecurityHandler);
- std::unique_ptr<CPDF_CryptoHandler> pCryptoHandler(
- m_pSecurityHandler->CreateCryptoHandler());
- if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler.get()))
- return HANDLER_ERROR;
- m_pSyntax->SetEncrypt(std::move(pCryptoHandler));
- }
- return SUCCESS;
-}
-
-void CPDF_Parser::ReleaseEncryptHandler() {
- m_pSyntax->m_pCryptoHandler.reset();
- m_pSecurityHandler.reset();
-}
-
-FX_FILESIZE CPDF_Parser::GetObjectOffset(uint32_t objnum) const {
- if (!IsValidObjectNumber(objnum))
- return 0;
-
- if (GetObjectType(objnum) == 1)
- return GetObjectPositionOrZero(objnum);
-
- if (GetObjectType(objnum) == 2) {
- FX_FILESIZE pos = GetObjectPositionOrZero(objnum);
- return GetObjectPositionOrZero(pos);
- }
- return 0;
-}
-
-// Ideally, all the cross reference entries should be verified.
-// In reality, we rarely see well-formed cross references don't match
-// with the objects. crbug/602650 showed a case where object numbers
-// in the cross reference table are all off by one.
-bool CPDF_Parser::VerifyCrossRefV4() {
- for (const auto& it : m_ObjectInfo) {
- if (it.second.pos == 0)
- continue;
- // Find the first non-zero position.
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
- m_pSyntax->RestorePos(it.second.pos);
- bool is_num = false;
- CFX_ByteString num_str = m_pSyntax->GetNextWord(&is_num);
- m_pSyntax->RestorePos(SavedPos);
- if (!is_num || num_str.IsEmpty() ||
- FXSYS_atoui(num_str.c_str()) != it.first) {
- // If the object number read doesn't match the one stored,
- // something is wrong with the cross reference table.
- return false;
- } else {
- return true;
- }
- }
- return true;
-}
-
-FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos) {
- if (!LoadCrossRefV4(xrefpos, 0, TRUE))
- return FALSE;
-
- m_pTrailer = LoadTrailerV4();
- if (!m_pTrailer)
- return FALSE;
-
- int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size");
- if (xrefsize > 0 && xrefsize <= kMaxXRefSize)
- ShrinkObjectMap(xrefsize);
-
- std::vector<FX_FILESIZE> CrossRefList;
- std::vector<FX_FILESIZE> XRefStreamList;
- std::set<FX_FILESIZE> seen_xrefpos;
-
- CrossRefList.push_back(xrefpos);
- XRefStreamList.push_back(GetDirectInteger(m_pTrailer, "XRefStm"));
- seen_xrefpos.insert(xrefpos);
-
- // When |m_pTrailer| doesn't have Prev entry or Prev entry value is not
- // numerical, GetDirectInteger() returns 0. Loading will end.
- xrefpos = GetDirectInteger(m_pTrailer, "Prev");
- while (xrefpos) {
- // Check for circular references.
- if (pdfium::ContainsKey(seen_xrefpos, xrefpos))
- return FALSE;
-
- seen_xrefpos.insert(xrefpos);
-
- // SLOW ...
- CrossRefList.insert(CrossRefList.begin(), xrefpos);
- LoadCrossRefV4(xrefpos, 0, TRUE);
-
- std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict(
- LoadTrailerV4());
- if (!pDict)
- return FALSE;
-
- xrefpos = GetDirectInteger(pDict.get(), "Prev");
-
- // SLOW ...
- XRefStreamList.insert(XRefStreamList.begin(),
- pDict->GetIntegerFor("XRefStm"));
- m_Trailers.Add(pDict.release());
- }
-
- for (size_t i = 0; i < CrossRefList.size(); ++i) {
- if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE))
- return FALSE;
- if (i == 0 && !VerifyCrossRefV4())
- return FALSE;
- }
- return TRUE;
-}
-
-FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos,
- uint32_t dwObjCount) {
- if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount))
- return FALSE;
-
- m_pTrailer = LoadTrailerV4();
- if (!m_pTrailer)
- return FALSE;
-
- int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size");
- if (xrefsize == 0)
- return FALSE;
-
- std::vector<FX_FILESIZE> CrossRefList;
- std::vector<FX_FILESIZE> XRefStreamList;
- std::set<FX_FILESIZE> seen_xrefpos;
-
- CrossRefList.push_back(xrefpos);
- XRefStreamList.push_back(GetDirectInteger(m_pTrailer, "XRefStm"));
- seen_xrefpos.insert(xrefpos);
-
- xrefpos = GetDirectInteger(m_pTrailer, "Prev");
- while (xrefpos) {
- // Check for circular references.
- if (pdfium::ContainsKey(seen_xrefpos, xrefpos))
- return FALSE;
-
- seen_xrefpos.insert(xrefpos);
-
- // SLOW ...
- CrossRefList.insert(CrossRefList.begin(), xrefpos);
- LoadCrossRefV4(xrefpos, 0, TRUE);
-
- std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict(
- LoadTrailerV4());
- if (!pDict)
- return FALSE;
-
- xrefpos = GetDirectInteger(pDict.get(), "Prev");
-
- // SLOW ...
- XRefStreamList.insert(XRefStreamList.begin(),
- pDict->GetIntegerFor("XRefStm"));
- m_Trailers.Add(pDict.release());
- }
-
- for (size_t i = 1; i < CrossRefList.size(); ++i) {
- if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE))
- return FALSE;
- }
- return TRUE;
-}
-
-FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos,
- uint32_t dwObjCount) {
- FX_FILESIZE dwStartPos = pos - m_pSyntax->m_HeaderOffset;
-
- m_pSyntax->RestorePos(dwStartPos);
- m_SortedOffset.insert(pos);
-
- uint32_t start_objnum = 0;
- uint32_t count = dwObjCount;
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
-
- const int32_t recordsize = 20;
- std::vector<char> buf(1024 * recordsize + 1);
- buf[1024 * recordsize] = '\0';
-
- int32_t nBlocks = count / 1024 + 1;
- for (int32_t block = 0; block < nBlocks; block++) {
- int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024;
- uint32_t dwReadSize = block_size * recordsize;
- if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_pSyntax->m_FileLen)
- return FALSE;
-
- if (!m_pSyntax->ReadBlock(reinterpret_cast<uint8_t*>(buf.data()),
- dwReadSize)) {
- return FALSE;
- }
-
- for (int32_t i = 0; i < block_size; i++) {
- uint32_t objnum = start_objnum + block * 1024 + i;
- char* pEntry = &buf[i * recordsize];
- if (pEntry[17] == 'f') {
- m_ObjectInfo[objnum].pos = 0;
- m_ObjectInfo[objnum].type = 0;
- } else {
- int32_t offset = FXSYS_atoi(pEntry);
- if (offset == 0) {
- for (int32_t c = 0; c < 10; c++) {
- if (!std::isdigit(pEntry[c]))
- return FALSE;
- }
- }
-
- m_ObjectInfo[objnum].pos = offset;
- int32_t version = FXSYS_atoi(pEntry + 11);
- if (version >= 1)
- m_bVersionUpdated = true;
-
- m_ObjectInfo[objnum].gennum = version;
- if (m_ObjectInfo[objnum].pos < m_pSyntax->m_FileLen)
- m_SortedOffset.insert(m_ObjectInfo[objnum].pos);
-
- m_ObjectInfo[objnum].type = 1;
- }
- }
- }
- m_pSyntax->RestorePos(SavedPos + count * recordsize);
- return TRUE;
-}
-
-bool CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos,
- FX_FILESIZE streampos,
- FX_BOOL bSkip) {
- m_pSyntax->RestorePos(pos);
- if (m_pSyntax->GetKeyword() != "xref")
- return false;
-
- m_SortedOffset.insert(pos);
- if (streampos)
- m_SortedOffset.insert(streampos);
-
- while (1) {
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
- bool bIsNumber;
- CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber);
- if (word.IsEmpty())
- return false;
-
- if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
- break;
- }
-
- uint32_t start_objnum = FXSYS_atoui(word.c_str());
- if (start_objnum >= kMaxObjectNumber)
- return false;
-
- uint32_t count = m_pSyntax->GetDirectNum();
- m_pSyntax->ToNextWord();
- SavedPos = m_pSyntax->SavePos();
- const int32_t recordsize = 20;
-
- m_dwXrefStartObjNum = start_objnum;
- if (!bSkip) {
- std::vector<char> buf(1024 * recordsize + 1);
- buf[1024 * recordsize] = '\0';
-
- int32_t nBlocks = count / 1024 + 1;
- for (int32_t block = 0; block < nBlocks; block++) {
- int32_t block_size = block == nBlocks - 1 ? count % 1024 : 1024;
- m_pSyntax->ReadBlock(reinterpret_cast<uint8_t*>(buf.data()),
- block_size * recordsize);
-
- for (int32_t i = 0; i < block_size; i++) {
- uint32_t objnum = start_objnum + block * 1024 + i;
- char* pEntry = &buf[i * recordsize];
- if (pEntry[17] == 'f') {
- m_ObjectInfo[objnum].pos = 0;
- m_ObjectInfo[objnum].type = 0;
- } else {
- FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);
- if (offset == 0) {
- for (int32_t c = 0; c < 10; c++) {
- if (!std::isdigit(pEntry[c]))
- return false;
- }
- }
-
- m_ObjectInfo[objnum].pos = offset;
- int32_t version = FXSYS_atoi(pEntry + 11);
- if (version >= 1)
- m_bVersionUpdated = true;
-
- m_ObjectInfo[objnum].gennum = version;
- if (m_ObjectInfo[objnum].pos < m_pSyntax->m_FileLen)
- m_SortedOffset.insert(m_ObjectInfo[objnum].pos);
-
- m_ObjectInfo[objnum].type = 1;
- }
- }
- }
- }
- m_pSyntax->RestorePos(SavedPos + count * recordsize);
- }
- return !streampos || LoadCrossRefV5(&streampos, FALSE);
-}
-
-FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos) {
- if (!LoadCrossRefV5(&xrefpos, TRUE))
- return FALSE;
-
- std::set<FX_FILESIZE> seen_xrefpos;
- while (xrefpos) {
- seen_xrefpos.insert(xrefpos);
- if (!LoadCrossRefV5(&xrefpos, FALSE))
- return FALSE;
-
- // Check for circular references.
- if (pdfium::ContainsKey(seen_xrefpos, xrefpos))
- return FALSE;
- }
- m_ObjectStreamMap.clear();
- m_bXRefStream = TRUE;
- return TRUE;
-}
-
-FX_BOOL CPDF_Parser::RebuildCrossRef() {
- m_ObjectInfo.clear();
- m_SortedOffset.clear();
- if (m_pTrailer) {
- m_pTrailer->Release();
- m_pTrailer = nullptr;
- }
-
- ParserState state = ParserState::kDefault;
-
- int32_t inside_index = 0;
- uint32_t objnum = 0;
- uint32_t gennum = 0;
- int32_t depth = 0;
-
- const uint32_t kBufferSize = 4096;
- std::vector<uint8_t> buffer(kBufferSize);
-
- FX_FILESIZE pos = m_pSyntax->m_HeaderOffset;
- FX_FILESIZE start_pos = 0;
- FX_FILESIZE start_pos1 = 0;
- FX_FILESIZE last_obj = -1;
- FX_FILESIZE last_xref = -1;
- FX_FILESIZE last_trailer = -1;
-
- while (pos < m_pSyntax->m_FileLen) {
- const FX_FILESIZE saved_pos = pos;
- bool bOverFlow = false;
- uint32_t size =
- std::min((uint32_t)(m_pSyntax->m_FileLen - pos), kBufferSize);
- if (!m_pSyntax->m_pFileAccess->ReadBlock(buffer.data(), pos, size))
- break;
-
- for (uint32_t i = 0; i < size; i++) {
- uint8_t byte = buffer[i];
- switch (state) {
- case ParserState::kDefault:
- if (PDFCharIsWhitespace(byte)) {
- state = ParserState::kWhitespace;
- } else if (std::isdigit(byte)) {
- --i;
- state = ParserState::kWhitespace;
- } else if (byte == '%') {
- inside_index = 0;
- state = ParserState::kComment;
- } else if (byte == '(') {
- state = ParserState::kString;
- depth = 1;
- } else if (byte == '<') {
- inside_index = 1;
- state = ParserState::kHexString;
- } else if (byte == '\\') {
- state = ParserState::kEscapedString;
- } else if (byte == 't') {
- state = ParserState::kTrailer;
- inside_index = 1;
- }
- break;
-
- case ParserState::kWhitespace:
- if (std::isdigit(byte)) {
- start_pos = pos + i;
- state = ParserState::kObjNum;
- objnum = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(byte));
- } else if (byte == 't') {
- state = ParserState::kTrailer;
- inside_index = 1;
- } else if (byte == 'x') {
- state = ParserState::kXref;
- inside_index = 1;
- } else if (!PDFCharIsWhitespace(byte)) {
- --i;
- state = ParserState::kDefault;
- }
- break;
-
- case ParserState::kObjNum:
- if (std::isdigit(byte)) {
- objnum =
- objnum * 10 + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(byte));
- } else if (PDFCharIsWhitespace(byte)) {
- state = ParserState::kPostObjNum;
- } else {
- --i;
- state = ParserState::kEndObj;
- inside_index = 0;
- }
- break;
-
- case ParserState::kPostObjNum:
- if (std::isdigit(byte)) {
- start_pos1 = pos + i;
- state = ParserState::kGenNum;
- gennum = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(byte));
- } else if (byte == 't') {
- state = ParserState::kTrailer;
- inside_index = 1;
- } else if (!PDFCharIsWhitespace(byte)) {
- --i;
- state = ParserState::kDefault;
- }
- break;
-
- case ParserState::kGenNum:
- if (std::isdigit(byte)) {
- gennum =
- gennum * 10 + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(byte));
- } else if (PDFCharIsWhitespace(byte)) {
- state = ParserState::kPostGenNum;
- } else {
- --i;
- state = ParserState::kDefault;
- }
- break;
-
- case ParserState::kPostGenNum:
- if (byte == 'o') {
- state = ParserState::kBeginObj;
- inside_index = 1;
- } else if (std::isdigit(byte)) {
- objnum = gennum;
- gennum = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(byte));
- start_pos = start_pos1;
- start_pos1 = pos + i;
- state = ParserState::kGenNum;
- } else if (byte == 't') {
- state = ParserState::kTrailer;
- inside_index = 1;
- } else if (!PDFCharIsWhitespace(byte)) {
- --i;
- state = ParserState::kDefault;
- }
- break;
-
- case ParserState::kBeginObj:
- switch (inside_index) {
- case 1:
- if (byte != 'b') {
- --i;
- state = ParserState::kDefault;
- } else {
- inside_index++;
- }
- break;
- case 2:
- if (byte != 'j') {
- --i;
- state = ParserState::kDefault;
- } else {
- inside_index++;
- }
- break;
- case 3:
- if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) {
- FX_FILESIZE obj_pos = start_pos - m_pSyntax->m_HeaderOffset;
- m_SortedOffset.insert(obj_pos);
- last_obj = start_pos;
- FX_FILESIZE obj_end = 0;
- CPDF_Object* pObject = ParseIndirectObjectAtByStrict(
- m_pDocument, obj_pos, objnum, &obj_end);
- if (CPDF_Stream* pStream = ToStream(pObject)) {
- if (CPDF_Dictionary* pDict = pStream->GetDict()) {
- if ((pDict->KeyExist("Type")) &&
- (pDict->GetStringFor("Type") == "XRef" &&
- pDict->KeyExist("Size"))) {
- CPDF_Object* pRoot = pDict->GetObjectFor("Root");
- if (pRoot && pRoot->GetDict() &&
- pRoot->GetDict()->GetObjectFor("Pages")) {
- if (m_pTrailer)
- m_pTrailer->Release();
- m_pTrailer = ToDictionary(pDict->Clone());
- }
- }
- }
- }
-
- FX_FILESIZE offset = 0;
- m_pSyntax->RestorePos(obj_pos);
- offset = m_pSyntax->FindTag("obj", 0);
- if (offset == -1)
- offset = 0;
- else
- offset += 3;
-
- FX_FILESIZE nLen = obj_end - obj_pos - offset;
- if ((uint32_t)nLen > size - i) {
- pos = obj_end + m_pSyntax->m_HeaderOffset;
- bOverFlow = true;
- } else {
- i += (uint32_t)nLen;
- }
-
- if (!m_ObjectInfo.empty() && IsValidObjectNumber(objnum) &&
- m_ObjectInfo[objnum].pos) {
- if (pObject) {
- uint32_t oldgen = GetObjectGenNum(objnum);
- m_ObjectInfo[objnum].pos = obj_pos;
- m_ObjectInfo[objnum].gennum = gennum;
- if (oldgen != gennum)
- m_bVersionUpdated = true;
- }
- } else {
- m_ObjectInfo[objnum].pos = obj_pos;
- m_ObjectInfo[objnum].type = 1;
- m_ObjectInfo[objnum].gennum = gennum;
- }
-
- if (pObject)
- pObject->Release();
- }
- --i;
- state = ParserState::kDefault;
- break;
- }
- break;
-
- case ParserState::kTrailer:
- if (inside_index == 7) {
- if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) {
- last_trailer = pos + i - 7;
- m_pSyntax->RestorePos(pos + i - m_pSyntax->m_HeaderOffset);
-
- CPDF_Object* pObj = m_pSyntax->GetObject(m_pDocument, 0, 0, true);
- if (pObj) {
- if (!pObj->IsDictionary() && !pObj->AsStream()) {
- pObj->Release();
- } else {
- CPDF_Stream* pStream = pObj->AsStream();
- if (CPDF_Dictionary* pTrailer =
- pStream ? pStream->GetDict() : pObj->AsDictionary()) {
- if (m_pTrailer) {
- CPDF_Object* pRoot = pTrailer->GetObjectFor("Root");
- CPDF_Reference* pRef = ToReference(pRoot);
- if (!pRoot ||
- (pRef && IsValidObjectNumber(pRef->GetRefObjNum()) &&
- m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) {
- auto it = pTrailer->begin();
- while (it != pTrailer->end()) {
- const CFX_ByteString& key = it->first;
- CPDF_Object* pElement = it->second;
- ++it;
- uint32_t dwObjNum =
- pElement ? pElement->GetObjNum() : 0;
- if (dwObjNum) {
- m_pTrailer->SetReferenceFor(key, m_pDocument,
- dwObjNum);
- } else {
- m_pTrailer->SetFor(key, pElement->Clone());
- }
- }
- }
- pObj->Release();
- } else {
- if (pObj->IsStream()) {
- m_pTrailer = ToDictionary(pTrailer->Clone());
- pObj->Release();
- } else {
- m_pTrailer = pTrailer;
- }
-
- FX_FILESIZE dwSavePos = m_pSyntax->SavePos();
- CFX_ByteString strWord = m_pSyntax->GetKeyword();
- if (!strWord.Compare("startxref")) {
- bool bNumber;
- CFX_ByteString bsOffset =
- m_pSyntax->GetNextWord(&bNumber);
- if (bNumber)
- m_LastXRefOffset = FXSYS_atoi(bsOffset.c_str());
- }
- m_pSyntax->RestorePos(dwSavePos);
- }
- } else {
- pObj->Release();
- }
- }
- }
- }
- --i;
- state = ParserState::kDefault;
- } else if (byte == "trailer"[inside_index]) {
- inside_index++;
- } else {
- --i;
- state = ParserState::kDefault;
- }
- break;
-
- case ParserState::kXref:
- if (inside_index == 4) {
- last_xref = pos + i - 4;
- state = ParserState::kWhitespace;
- } else if (byte == "xref"[inside_index]) {
- inside_index++;
- } else {
- --i;
- state = ParserState::kDefault;
- }
- break;
-
- case ParserState::kComment:
- if (PDFCharIsLineEnding(byte))
- state = ParserState::kDefault;
- break;
-
- case ParserState::kString:
- if (byte == ')') {
- if (depth > 0)
- depth--;
- } else if (byte == '(') {
- depth++;
- }
-
- if (!depth)
- state = ParserState::kDefault;
- break;
-
- case ParserState::kHexString:
- if (byte == '>' || (byte == '<' && inside_index == 1))
- state = ParserState::kDefault;
- inside_index = 0;
- break;
-
- case ParserState::kEscapedString:
- if (PDFCharIsDelimiter(byte) || PDFCharIsWhitespace(byte)) {
- --i;
- state = ParserState::kDefault;
- }
- break;
-
- case ParserState::kEndObj:
- if (PDFCharIsWhitespace(byte)) {
- state = ParserState::kDefault;
- } else if (byte == '%' || byte == '(' || byte == '<' ||
- byte == '\\') {
- state = ParserState::kDefault;
- --i;
- } else if (inside_index == 6) {
- state = ParserState::kDefault;
- --i;
- } else if (byte == "endobj"[inside_index]) {
- inside_index++;
- }
- break;
- }
-
- if (bOverFlow) {
- size = 0;
- break;
- }
- }
- pos += size;
-
- // If the position has not changed at all or went backwards in a loop
- // iteration, then break out to prevent infinite looping.
- if (pos <= saved_pos)
- break;
- }
-
- if (last_xref != -1 && last_xref > last_obj)
- last_trailer = last_xref;
- else if (last_trailer == -1 || last_xref < last_obj)
- last_trailer = m_pSyntax->m_FileLen;
-
- m_SortedOffset.insert(last_trailer - m_pSyntax->m_HeaderOffset);
- return m_pTrailer && !m_ObjectInfo.empty();
-}
-
-FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) {
- CPDF_Object* pObject = ParseIndirectObjectAt(m_pDocument, *pos, 0);
- if (!pObject)
- return FALSE;
-
- if (m_pDocument) {
- CPDF_Dictionary* pRootDict = m_pDocument->GetRoot();
- if (pRootDict && pRootDict->GetObjNum() == pObject->m_ObjNum) {
- // If |pObject| has an objnum assigned then this will leak as Release()
- // will early exit.
- if (pObject->IsStream())
- pObject->Release();
- return FALSE;
- }
- if (!m_pDocument->ReplaceIndirectObjectIfHigherGeneration(pObject->m_ObjNum,
- pObject)) {
- return FALSE;
- }
- }
-
- CPDF_Stream* pStream = pObject->AsStream();
- if (!pStream)
- return FALSE;
-
- CPDF_Dictionary* pDict = pStream->GetDict();
- *pos = pDict->GetIntegerFor("Prev");
- int32_t size = pDict->GetIntegerFor("Size");
- if (size < 0) {
- pStream->Release();
- return FALSE;
- }
-
- CPDF_Dictionary* pNewTrailer = ToDictionary(pDict->Clone());
- if (bMainXRef) {
- m_pTrailer = pNewTrailer;
- ShrinkObjectMap(size);
- for (auto& it : m_ObjectInfo)
- it.second.type = 0;
- } else {
- m_Trailers.Add(pNewTrailer);
- }
-
- std::vector<std::pair<int32_t, int32_t>> arrIndex;
- CPDF_Array* pArray = pDict->GetArrayFor("Index");
- if (pArray) {
- for (size_t i = 0; i < pArray->GetCount() / 2; i++) {
- CPDF_Object* pStartNumObj = pArray->GetObjectAt(i * 2);
- CPDF_Object* pCountObj = pArray->GetObjectAt(i * 2 + 1);
-
- if (ToNumber(pStartNumObj) && ToNumber(pCountObj)) {
- int nStartNum = pStartNumObj->GetInteger();
- int nCount = pCountObj->GetInteger();
- if (nStartNum >= 0 && nCount > 0)
- arrIndex.push_back(std::make_pair(nStartNum, nCount));
- }
- }
- }
-
- if (arrIndex.size() == 0)
- arrIndex.push_back(std::make_pair(0, size));
-
- pArray = pDict->GetArrayFor("W");
- if (!pArray) {
- pStream->Release();
- return FALSE;
- }
-
- CFX_ArrayTemplate<uint32_t> WidthArray;
- FX_SAFE_UINT32 dwAccWidth = 0;
- for (size_t i = 0; i < pArray->GetCount(); ++i) {
- WidthArray.Add(pArray->GetIntegerAt(i));
- dwAccWidth += WidthArray[i];
- }
-
- if (!dwAccWidth.IsValid() || WidthArray.GetSize() < 3) {
- pStream->Release();
- return FALSE;
- }
-
- uint32_t totalWidth = dwAccWidth.ValueOrDie();
- CPDF_StreamAcc acc;
- acc.LoadAllData(pStream);
-
- const uint8_t* pData = acc.GetData();
- uint32_t dwTotalSize = acc.GetSize();
- uint32_t segindex = 0;
- for (uint32_t i = 0; i < arrIndex.size(); i++) {
- int32_t startnum = arrIndex[i].first;
- if (startnum < 0)
- continue;
-
- m_dwXrefStartObjNum =
- pdfium::base::checked_cast<uint32_t, int32_t>(startnum);
- uint32_t count =
- pdfium::base::checked_cast<uint32_t, int32_t>(arrIndex[i].second);
- FX_SAFE_UINT32 dwCaculatedSize = segindex;
- dwCaculatedSize += count;
- dwCaculatedSize *= totalWidth;
- if (!dwCaculatedSize.IsValid() ||
- dwCaculatedSize.ValueOrDie() > dwTotalSize) {
- continue;
- }
-
- const uint8_t* segstart = pData + segindex * totalWidth;
- FX_SAFE_UINT32 dwMaxObjNum = startnum;
- dwMaxObjNum += count;
- uint32_t dwV5Size = m_ObjectInfo.empty() ? 0 : GetLastObjNum() + 1;
- if (!dwMaxObjNum.IsValid() || dwMaxObjNum.ValueOrDie() > dwV5Size)
- continue;
-
- for (uint32_t j = 0; j < count; j++) {
- int32_t type = 1;
- const uint8_t* entrystart = segstart + j * totalWidth;
- if (WidthArray[0])
- type = GetVarInt(entrystart, WidthArray[0]);
-
- if (GetObjectType(startnum + j) == 255) {
- FX_FILESIZE offset =
- GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
- m_ObjectInfo[startnum + j].pos = offset;
- m_SortedOffset.insert(offset);
- continue;
- }
-
- if (GetObjectType(startnum + j))
- continue;
-
- m_ObjectInfo[startnum + j].type = type;
- if (type == 0) {
- m_ObjectInfo[startnum + j].pos = 0;
- } else {
- FX_FILESIZE offset =
- GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
- m_ObjectInfo[startnum + j].pos = offset;
- if (type == 1) {
- m_SortedOffset.insert(offset);
- } else {
- if (offset < 0 || !IsValidObjectNumber(offset)) {
- pStream->Release();
- return FALSE;
- }
- m_ObjectInfo[offset].type = 255;
- }
- }
- }
- segindex += count;
- }
- pStream->Release();
- return TRUE;
-}
-
-CPDF_Array* CPDF_Parser::GetIDArray() {
- CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetObjectFor("ID") : nullptr;
- if (!pID)
- return nullptr;
-
- if (CPDF_Reference* pRef = pID->AsReference()) {
- pID = ParseIndirectObject(nullptr, pRef->GetRefObjNum());
- m_pTrailer->SetFor("ID", pID);
- }
- return ToArray(pID);
-}
-
-uint32_t CPDF_Parser::GetRootObjNum() {
- CPDF_Reference* pRef =
- ToReference(m_pTrailer ? m_pTrailer->GetObjectFor("Root") : nullptr);
- return pRef ? pRef->GetRefObjNum() : 0;
-}
-
-uint32_t CPDF_Parser::GetInfoObjNum() {
- CPDF_Reference* pRef =
- ToReference(m_pTrailer ? m_pTrailer->GetObjectFor("Info") : nullptr);
- return pRef ? pRef->GetRefObjNum() : 0;
-}
-
-CPDF_Object* CPDF_Parser::ParseIndirectObject(
- CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum) {
- if (!IsValidObjectNumber(objnum))
- return nullptr;
-
- // Prevent circular parsing the same object.
- if (pdfium::ContainsKey(m_ParsingObjNums, objnum))
- return nullptr;
-
- pdfium::ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums, objnum);
- if (GetObjectType(objnum) == 1 || GetObjectType(objnum) == 255) {
- FX_FILESIZE pos = m_ObjectInfo[objnum].pos;
- if (pos <= 0)
- return nullptr;
- return ParseIndirectObjectAt(pObjList, pos, objnum);
- }
- if (GetObjectType(objnum) != 2)
- return nullptr;
-
- CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos);
- if (!pObjStream)
- return nullptr;
-
- ScopedFileStream file(FX_CreateMemoryStream(
- (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE));
- CPDF_SyntaxParser syntax;
- syntax.InitParser(file.get(), 0);
- const int32_t offset = GetStreamFirst(pObjStream);
-
- // Read object numbers from |pObjStream| into a cache.
- if (!pdfium::ContainsKey(m_ObjCache, pObjStream)) {
- for (int32_t i = GetStreamNCount(pObjStream); i > 0; --i) {
- uint32_t thisnum = syntax.GetDirectNum();
- uint32_t thisoff = syntax.GetDirectNum();
- m_ObjCache[pObjStream][thisnum] = thisoff;
- }
- }
-
- const auto it = m_ObjCache[pObjStream].find(objnum);
- if (it == m_ObjCache[pObjStream].end())
- return nullptr;
-
- syntax.RestorePos(offset + it->second);
- return syntax.GetObject(pObjList, 0, 0, true);
-}
-
-CPDF_StreamAcc* CPDF_Parser::GetObjectStream(uint32_t objnum) {
- auto it = m_ObjectStreamMap.find(objnum);
- if (it != m_ObjectStreamMap.end())
- return it->second.get();
-
- if (!m_pDocument)
- return nullptr;
-
- const CPDF_Stream* pStream =
- ToStream(m_pDocument->GetOrParseIndirectObject(objnum));
- if (!pStream)
- return nullptr;
-
- CPDF_StreamAcc* pStreamAcc = new CPDF_StreamAcc;
- pStreamAcc->LoadAllData(pStream);
- m_ObjectStreamMap[objnum].reset(pStreamAcc);
- return pStreamAcc;
-}
-
-FX_FILESIZE CPDF_Parser::GetObjectSize(uint32_t objnum) const {
- if (!IsValidObjectNumber(objnum))
- return 0;
-
- if (GetObjectType(objnum) == 2)
- objnum = GetObjectPositionOrZero(objnum);
-
- if (GetObjectType(objnum) != 1 && GetObjectType(objnum) != 255)
- return 0;
-
- FX_FILESIZE offset = GetObjectPositionOrZero(objnum);
- if (offset == 0)
- return 0;
-
- auto it = m_SortedOffset.find(offset);
- if (it == m_SortedOffset.end() || ++it == m_SortedOffset.end())
- return 0;
-
- return *it - offset;
-}
-
-void CPDF_Parser::GetIndirectBinary(uint32_t objnum,
- uint8_t*& pBuffer,
- uint32_t& size) {
- pBuffer = nullptr;
- size = 0;
- if (!IsValidObjectNumber(objnum))
- return;
-
- if (GetObjectType(objnum) == 2) {
- CPDF_StreamAcc* pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos);
- if (!pObjStream)
- return;
-
- int32_t offset = GetStreamFirst(pObjStream);
- const uint8_t* pData = pObjStream->GetData();
- uint32_t totalsize = pObjStream->GetSize();
- ScopedFileStream file(
- FX_CreateMemoryStream((uint8_t*)pData, (size_t)totalsize, FALSE));
-
- CPDF_SyntaxParser syntax;
- syntax.InitParser(file.get(), 0);
- for (int i = GetStreamNCount(pObjStream); i > 0; --i) {
- uint32_t thisnum = syntax.GetDirectNum();
- uint32_t thisoff = syntax.GetDirectNum();
- if (thisnum != objnum)
- continue;
-
- if (i == 1) {
- size = totalsize - (thisoff + offset);
- } else {
- syntax.GetDirectNum(); // Skip nextnum.
- uint32_t nextoff = syntax.GetDirectNum();
- size = nextoff - thisoff;
- }
-
- pBuffer = FX_Alloc(uint8_t, size);
- FXSYS_memcpy(pBuffer, pData + thisoff + offset, size);
- return;
- }
- return;
- }
-
- if (GetObjectType(objnum) != 1)
- return;
-
- FX_FILESIZE pos = m_ObjectInfo[objnum].pos;
- if (pos == 0)
- return;
-
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
- m_pSyntax->RestorePos(pos);
-
- bool bIsNumber;
- CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber);
- if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
- return;
- }
-
- uint32_t parser_objnum = FXSYS_atoui(word.c_str());
- if (parser_objnum && parser_objnum != objnum) {
- m_pSyntax->RestorePos(SavedPos);
- return;
- }
-
- word = m_pSyntax->GetNextWord(&bIsNumber);
- if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
- return;
- }
-
- if (m_pSyntax->GetKeyword() != "obj") {
- m_pSyntax->RestorePos(SavedPos);
- return;
- }
-
- auto it = m_SortedOffset.find(pos);
- if (it == m_SortedOffset.end() || ++it == m_SortedOffset.end()) {
- m_pSyntax->RestorePos(SavedPos);
- return;
- }
-
- FX_FILESIZE nextoff = *it;
- FX_BOOL bNextOffValid = FALSE;
- if (nextoff != pos) {
- m_pSyntax->RestorePos(nextoff);
- word = m_pSyntax->GetNextWord(&bIsNumber);
- if (word == "xref") {
- bNextOffValid = TRUE;
- } else if (bIsNumber) {
- word = m_pSyntax->GetNextWord(&bIsNumber);
- if (bIsNumber && m_pSyntax->GetKeyword() == "obj") {
- bNextOffValid = TRUE;
- }
- }
- }
-
- if (!bNextOffValid) {
- m_pSyntax->RestorePos(pos);
- while (1) {
- if (m_pSyntax->GetKeyword() == "endobj")
- break;
-
- if (m_pSyntax->SavePos() == m_pSyntax->m_FileLen)
- break;
- }
- nextoff = m_pSyntax->SavePos();
- }
-
- size = (uint32_t)(nextoff - pos);
- pBuffer = FX_Alloc(uint8_t, size);
- m_pSyntax->RestorePos(pos);
- m_pSyntax->ReadBlock(pBuffer, size);
- m_pSyntax->RestorePos(SavedPos);
-}
-
-CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(
- CPDF_IndirectObjectHolder* pObjList,
- FX_FILESIZE pos,
- uint32_t objnum) {
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
- m_pSyntax->RestorePos(pos);
- bool bIsNumber;
- CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber);
- if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
- return nullptr;
- }
-
- FX_FILESIZE objOffset = m_pSyntax->SavePos();
- objOffset -= word.GetLength();
- uint32_t parser_objnum = FXSYS_atoui(word.c_str());
- if (objnum && parser_objnum != objnum) {
- m_pSyntax->RestorePos(SavedPos);
- return nullptr;
- }
-
- word = m_pSyntax->GetNextWord(&bIsNumber);
- if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
- return nullptr;
- }
-
- uint32_t parser_gennum = FXSYS_atoui(word.c_str());
- if (m_pSyntax->GetKeyword() != "obj") {
- m_pSyntax->RestorePos(SavedPos);
- return nullptr;
- }
-
- CPDF_Object* pObj =
- m_pSyntax->GetObject(pObjList, objnum, parser_gennum, true);
- m_pSyntax->SavePos();
-
- CFX_ByteString bsWord = m_pSyntax->GetKeyword();
- if (bsWord == "endobj")
- m_pSyntax->SavePos();
-
- m_pSyntax->RestorePos(SavedPos);
- if (pObj) {
- if (!objnum)
- pObj->m_ObjNum = parser_objnum;
- pObj->m_GenNum = parser_gennum;
- }
- return pObj;
-}
-
-CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict(
- CPDF_IndirectObjectHolder* pObjList,
- FX_FILESIZE pos,
- uint32_t objnum,
- FX_FILESIZE* pResultPos) {
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
- m_pSyntax->RestorePos(pos);
-
- bool bIsNumber;
- CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber);
- if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
- return nullptr;
- }
-
- uint32_t parser_objnum = FXSYS_atoui(word.c_str());
- if (objnum && parser_objnum != objnum) {
- m_pSyntax->RestorePos(SavedPos);
- return nullptr;
- }
-
- word = m_pSyntax->GetNextWord(&bIsNumber);
- if (!bIsNumber) {
- m_pSyntax->RestorePos(SavedPos);
- return nullptr;
- }
-
- uint32_t gennum = FXSYS_atoui(word.c_str());
- if (m_pSyntax->GetKeyword() != "obj") {
- m_pSyntax->RestorePos(SavedPos);
- return nullptr;
- }
-
- CPDF_Object* pObj = m_pSyntax->GetObjectForStrict(pObjList, objnum, gennum);
- if (pResultPos)
- *pResultPos = m_pSyntax->m_Pos;
-
- m_pSyntax->RestorePos(SavedPos);
- return pObj;
-}
-
-CPDF_Dictionary* CPDF_Parser::LoadTrailerV4() {
- if (m_pSyntax->GetKeyword() != "trailer")
- return nullptr;
-
- std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj(
- m_pSyntax->GetObject(m_pDocument, 0, 0, true));
- if (!ToDictionary(pObj.get()))
- return nullptr;
- return pObj.release()->AsDictionary();
-}
-
-uint32_t CPDF_Parser::GetPermissions() const {
- if (!m_pSecurityHandler)
- return 0xFFFFFFFF;
-
- uint32_t dwPermission = m_pSecurityHandler->GetPermissions();
- if (m_pEncryptDict && m_pEncryptDict->GetStringFor("Filter") == "Standard") {
- // See PDF Reference 1.7, page 123, table 3.20.
- dwPermission &= 0xFFFFFFFC;
- dwPermission |= 0xFFFFF0C0;
- }
- return dwPermission;
-}
-
-FX_BOOL CPDF_Parser::IsLinearizedFile(IFX_FileRead* pFileAccess,
- uint32_t offset) {
- m_pSyntax->InitParser(pFileAccess, offset);
- m_pSyntax->RestorePos(m_pSyntax->m_HeaderOffset + 9);
-
- FX_FILESIZE SavedPos = m_pSyntax->SavePos();
- bool bIsNumber;
- CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber);
- if (!bIsNumber)
- return FALSE;
-
- uint32_t objnum = FXSYS_atoui(word.c_str());
- word = m_pSyntax->GetNextWord(&bIsNumber);
- if (!bIsNumber)
- return FALSE;
-
- uint32_t gennum = FXSYS_atoui(word.c_str());
- if (m_pSyntax->GetKeyword() != "obj") {
- m_pSyntax->RestorePos(SavedPos);
- return FALSE;
- }
-
- m_pLinearized = m_pSyntax->GetObject(nullptr, objnum, gennum, true);
- if (!m_pLinearized)
- return FALSE;
-
- CPDF_Dictionary* pDict = m_pLinearized->GetDict();
- if (pDict && pDict->GetObjectFor("Linearized")) {
- m_pSyntax->GetNextWord(nullptr);
-
- CPDF_Object* pLen = pDict->GetObjectFor("L");
- if (!pLen) {
- m_pLinearized->Release();
- m_pLinearized = nullptr;
- return FALSE;
- }
-
- if (pLen->GetInteger() != (int)pFileAccess->GetSize())
- return FALSE;
-
- if (CPDF_Number* pNo = ToNumber(pDict->GetObjectFor("P")))
- m_dwFirstPageNo = pNo->GetInteger();
-
- if (CPDF_Number* pTable = ToNumber(pDict->GetObjectFor("T")))
- m_LastXRefOffset = pTable->GetInteger();
-
- return TRUE;
- }
- m_pLinearized->Release();
- m_pLinearized = nullptr;
- return FALSE;
-}
-
-CPDF_Parser::Error CPDF_Parser::StartLinearizedParse(IFX_FileRead* pFileAccess,
- CPDF_Document* pDocument) {
- ASSERT(!m_bHasParsed);
-
- m_bXRefStream = FALSE;
- m_LastXRefOffset = 0;
- m_bOwnFileRead = true;
-
- int32_t offset = GetHeaderOffset(pFileAccess);
- if (offset == -1)
- return FORMAT_ERROR;
-
- if (!IsLinearizedFile(pFileAccess, offset)) {
- m_pSyntax->m_pFileAccess = nullptr;
- return StartParse(pFileAccess, std::move(pDocument));
- }
- m_bHasParsed = true;
- m_pDocument = pDocument;
-
- FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos();
-
- FX_BOOL bXRefRebuilt = FALSE;
- FX_BOOL bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE);
- if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, TRUE)) {
- if (!RebuildCrossRef())
- return FORMAT_ERROR;
-
- bXRefRebuilt = TRUE;
- m_LastXRefOffset = 0;
- }
-
- if (bLoadV4) {
- m_pTrailer = LoadTrailerV4();
- if (!m_pTrailer)
- return SUCCESS;
-
- int32_t xrefsize = GetDirectInteger(m_pTrailer, "Size");
- if (xrefsize > 0)
- ShrinkObjectMap(xrefsize);
- }
-
- Error eRet = SetEncryptHandler();
- if (eRet != SUCCESS)
- return eRet;
-
- m_pDocument->LoadLinearizedDoc(m_pLinearized->GetDict());
- if (!m_pDocument->GetRoot() || m_pDocument->GetPageCount() == 0) {
- if (bXRefRebuilt)
- return FORMAT_ERROR;
-
- ReleaseEncryptHandler();
- if (!RebuildCrossRef())
- return FORMAT_ERROR;
-
- eRet = SetEncryptHandler();
- if (eRet != SUCCESS)
- return eRet;
-
- m_pDocument->LoadLinearizedDoc(m_pLinearized->GetDict());
- if (!m_pDocument->GetRoot())
- return FORMAT_ERROR;
- }
-
- if (GetRootObjNum() == 0) {
- ReleaseEncryptHandler();
- if (!RebuildCrossRef() || GetRootObjNum() == 0)
- return FORMAT_ERROR;
-
- eRet = SetEncryptHandler();
- if (eRet != SUCCESS)
- return eRet;
- }
-
- if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) {
- if (CPDF_Reference* pMetadata =
- ToReference(m_pDocument->GetRoot()->GetObjectFor("Metadata")))
- m_pSyntax->m_MetadataObjnum = pMetadata->GetRefObjNum();
- }
- return SUCCESS;
-}
-
-FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos) {
- if (!LoadCrossRefV5(&xrefpos, FALSE))
- return FALSE;
-
- std::set<FX_FILESIZE> seen_xrefpos;
- while (xrefpos) {
- seen_xrefpos.insert(xrefpos);
- if (!LoadCrossRefV5(&xrefpos, FALSE))
- return FALSE;
-
- // Check for circular references.
- if (pdfium::ContainsKey(seen_xrefpos, xrefpos))
- return FALSE;
- }
- m_ObjectStreamMap.clear();
- m_bXRefStream = TRUE;
- return TRUE;
-}
-
-CPDF_Parser::Error CPDF_Parser::LoadLinearizedMainXRefTable() {
- uint32_t dwSaveMetadataObjnum = m_pSyntax->m_MetadataObjnum;
- m_pSyntax->m_MetadataObjnum = 0;
- if (m_pTrailer) {
- m_pTrailer->Release();
- m_pTrailer = nullptr;
- }
-
- m_pSyntax->RestorePos(m_LastXRefOffset - m_pSyntax->m_HeaderOffset);
- uint8_t ch = 0;
- uint32_t dwCount = 0;
- m_pSyntax->GetNextChar(ch);
- while (PDFCharIsWhitespace(ch)) {
- ++dwCount;
- if (m_pSyntax->m_FileLen >=
- (FX_FILESIZE)(m_pSyntax->SavePos() + m_pSyntax->m_HeaderOffset)) {
- break;
- }
- m_pSyntax->GetNextChar(ch);
- }
- m_LastXRefOffset += dwCount;
- m_ObjectStreamMap.clear();
- m_ObjCache.clear();
-
- if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) &&
- !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) {
- m_LastXRefOffset = 0;
- m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum;
- return FORMAT_ERROR;
- }
-
- m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum;
- return SUCCESS;
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_parser.h b/core/fpdfapi/fpdf_parser/cpdf_parser.h
deleted file mode 100644
index 254b8b0274..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_parser.h
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_PARSER_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_PARSER_H_
-
-#include <map>
-#include <memory>
-#include <set>
-
-#include "core/fxcrt/fx_basic.h"
-
-class CPDF_Array;
-class CPDF_CryptoHandler;
-class CPDF_Dictionary;
-class CPDF_Document;
-class CPDF_IndirectObjectHolder;
-class CPDF_Object;
-class CPDF_SecurityHandler;
-class CPDF_StreamAcc;
-class CPDF_SyntaxParser;
-class IFX_FileRead;
-
-class CPDF_Parser {
- public:
- enum Error {
- SUCCESS = 0,
- FILE_ERROR,
- FORMAT_ERROR,
- PASSWORD_ERROR,
- HANDLER_ERROR
- };
-
- // A limit on the maximum object number in the xref table. Theoretical limits
- // are higher, but this may be large enough in practice.
- static const uint32_t kMaxObjectNumber = 1048576;
-
- CPDF_Parser();
- ~CPDF_Parser();
-
- Error StartParse(IFX_FileRead* pFile, CPDF_Document* pDocument);
- Error StartLinearizedParse(IFX_FileRead* pFile, CPDF_Document* pDocument);
-
- void SetPassword(const FX_CHAR* password) { m_Password = password; }
- CFX_ByteString GetPassword() { return m_Password; }
- CPDF_Dictionary* GetTrailer() const { return m_pTrailer; }
- FX_FILESIZE GetLastXRefOffset() const { return m_LastXRefOffset; }
-
- uint32_t GetPermissions() const;
- uint32_t GetRootObjNum();
- uint32_t GetInfoObjNum();
- CPDF_Array* GetIDArray();
-
- CPDF_Dictionary* GetEncryptDict() const { return m_pEncryptDict; }
-
- CPDF_Object* ParseIndirectObject(CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum);
-
- uint32_t GetLastObjNum() const;
- bool IsValidObjectNumber(uint32_t objnum) const;
- FX_FILESIZE GetObjectPositionOrZero(uint32_t objnum) const;
- uint8_t GetObjectType(uint32_t objnum) const;
- uint16_t GetObjectGenNum(uint32_t objnum) const;
- bool IsVersionUpdated() const { return m_bVersionUpdated; }
- bool IsObjectFreeOrNull(uint32_t objnum) const;
- CPDF_CryptoHandler* GetCryptoHandler();
- IFX_FileRead* GetFileAccess() const;
-
- FX_FILESIZE GetObjectOffset(uint32_t objnum) const;
- FX_FILESIZE GetObjectSize(uint32_t objnum) const;
-
- void GetIndirectBinary(uint32_t objnum, uint8_t*& pBuffer, uint32_t& size);
- int GetFileVersion() const { return m_FileVersion; }
- FX_BOOL IsXRefStream() const { return m_bXRefStream; }
-
- CPDF_Object* ParseIndirectObjectAt(CPDF_IndirectObjectHolder* pObjList,
- FX_FILESIZE pos,
- uint32_t objnum);
-
- CPDF_Object* ParseIndirectObjectAtByStrict(
- CPDF_IndirectObjectHolder* pObjList,
- FX_FILESIZE pos,
- uint32_t objnum,
- FX_FILESIZE* pResultPos);
-
- uint32_t GetFirstPageNo() const { return m_dwFirstPageNo; }
-
- protected:
- struct ObjectInfo {
- ObjectInfo() : pos(0), type(0), gennum(0) {}
-
- FX_FILESIZE pos;
- uint8_t type;
- uint16_t gennum;
- };
-
- std::unique_ptr<CPDF_SyntaxParser> m_pSyntax;
- std::map<uint32_t, ObjectInfo> m_ObjectInfo;
-
- bool LoadCrossRefV4(FX_FILESIZE pos, FX_FILESIZE streampos, FX_BOOL bSkip);
- FX_BOOL RebuildCrossRef();
-
- private:
- friend class CPDF_DataAvail;
-
- enum class ParserState {
- kDefault,
- kComment,
- kWhitespace,
- kString,
- kHexString,
- kEscapedString,
- kXref,
- kObjNum,
- kPostObjNum,
- kGenNum,
- kPostGenNum,
- kTrailer,
- kBeginObj,
- kEndObj
- };
-
- CPDF_Object* ParseDirect(CPDF_Object* pObj);
- FX_BOOL LoadAllCrossRefV4(FX_FILESIZE pos);
- FX_BOOL LoadAllCrossRefV5(FX_FILESIZE pos);
- FX_BOOL LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef);
- CPDF_Dictionary* LoadTrailerV4();
- Error SetEncryptHandler();
- void ReleaseEncryptHandler();
- FX_BOOL LoadLinearizedAllCrossRefV4(FX_FILESIZE pos, uint32_t dwObjCount);
- FX_BOOL LoadLinearizedCrossRefV4(FX_FILESIZE pos, uint32_t dwObjCount);
- FX_BOOL LoadLinearizedAllCrossRefV5(FX_FILESIZE pos);
- Error LoadLinearizedMainXRefTable();
- CPDF_StreamAcc* GetObjectStream(uint32_t number);
- FX_BOOL IsLinearizedFile(IFX_FileRead* pFileAccess, uint32_t offset);
- void SetEncryptDictionary(CPDF_Dictionary* pDict);
- void ShrinkObjectMap(uint32_t size);
- // A simple check whether the cross reference table matches with
- // the objects.
- bool VerifyCrossRefV4();
-
- CPDF_Document* m_pDocument; // not owned
- bool m_bHasParsed;
- bool m_bOwnFileRead;
- int m_FileVersion;
- CPDF_Dictionary* m_pTrailer;
- CPDF_Dictionary* m_pEncryptDict;
- FX_FILESIZE m_LastXRefOffset;
- FX_BOOL m_bXRefStream;
- std::unique_ptr<CPDF_SecurityHandler> m_pSecurityHandler;
- CFX_ByteString m_Password;
- std::set<FX_FILESIZE> m_SortedOffset;
- CFX_ArrayTemplate<CPDF_Dictionary*> m_Trailers;
- bool m_bVersionUpdated;
- CPDF_Object* m_pLinearized;
- uint32_t m_dwFirstPageNo;
- uint32_t m_dwXrefStartObjNum;
-
- // A map of object numbers to indirect streams. Map owns the streams.
- std::map<uint32_t, std::unique_ptr<CPDF_StreamAcc>> m_ObjectStreamMap;
-
- // Mapping of object numbers to offsets. The offsets are relative to the first
- // object in the stream.
- using StreamObjectCache = std::map<uint32_t, uint32_t>;
-
- // Mapping of streams to their object caches. This is valid as long as the
- // streams in |m_ObjectStreamMap| are valid.
- std::map<CPDF_StreamAcc*, StreamObjectCache> m_ObjCache;
-
- // All indirect object numbers that are being parsed.
- std::set<uint32_t> m_ParsingObjNums;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_PARSER_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_parser_embeddertest.cpp b/core/fpdfapi/fpdf_parser/cpdf_parser_embeddertest.cpp
deleted file mode 100644
index f523d6b31b..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_parser_embeddertest.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2015 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "public/fpdf_text.h"
-#include "testing/embedder_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-class CPDFParserEmbeddertest : public EmbedderTest {};
-
-TEST_F(CPDFParserEmbeddertest, LoadError_454695) {
- // Test a dictionary with hex string instead of correct content.
- // Verify that the defective pdf shouldn't be opened correctly.
- EXPECT_FALSE(OpenDocument("bug_454695.pdf"));
-}
-
-TEST_F(CPDFParserEmbeddertest, Bug_481363) {
- // Test colorspace object with malformed dictionary.
- EXPECT_TRUE(OpenDocument("bug_481363.pdf"));
- FPDF_PAGE page = LoadPage(0);
- EXPECT_NE(nullptr, page);
- UnloadPage(page);
-}
-
-TEST_F(CPDFParserEmbeddertest, Bug_544880) {
- // Test self referencing /Pages object.
- EXPECT_TRUE(OpenDocument("bug_544880.pdf"));
- // Shouldn't crash. We don't check the return value here because we get the
- // the count from the "/Count 1" in the testcase (at the time of writing)
- // rather than the actual count (0).
- (void)GetPageCount();
-}
-
-TEST_F(CPDFParserEmbeddertest, Feature_Linearized_Loading) {
- EXPECT_TRUE(OpenDocument("feature_linearized_loading.pdf", nullptr, true));
-}
-
-TEST_F(CPDFParserEmbeddertest, Bug_325a) {
- EXPECT_FALSE(OpenDocument("bug_325_a.pdf"));
-}
-
-TEST_F(CPDFParserEmbeddertest, Bug_325b) {
- EXPECT_FALSE(OpenDocument("bug_325_b.pdf"));
-}
-
-TEST_F(CPDFParserEmbeddertest, Bug_602650) {
- // Test the case that cross reference entries, which are well formed,
- // but do not match with the objects.
- EXPECT_TRUE(OpenDocument("bug_602650.pdf"));
- FPDF_PAGE page = LoadPage(0);
- EXPECT_NE(nullptr, page);
- FPDF_TEXTPAGE text_page = FPDFText_LoadPage(page);
- EXPECT_NE(nullptr, text_page);
- // The page should not be blank.
- EXPECT_LT(0, FPDFText_CountChars(text_page));
-
- FPDFText_ClosePage(text_page);
- UnloadPage(page);
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_parser_unittest.cpp b/core/fpdfapi/fpdf_parser/cpdf_parser_unittest.cpp
deleted file mode 100644
index 9c1de09eb1..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_parser_unittest.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2015 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <limits>
-#include <string>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_parser.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h"
-#include "core/fxcrt/fx_ext.h"
-#include "core/fxcrt/fx_stream.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/utils/path_service.h"
-
-// Provide a way to read test data from a buffer instead of a file.
-class CFX_TestBufferRead : public IFX_FileRead {
- public:
- CFX_TestBufferRead(const unsigned char* buffer_in, size_t buf_size)
- : buffer_(buffer_in), total_size_(buf_size) {}
-
- // IFX_Stream
- void Release() override { delete this; }
-
- // IFX_FileRead
- FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
- if (offset < 0 || offset + size > total_size_) {
- return FALSE;
- }
-
- memcpy(buffer, buffer_ + offset, size);
- return TRUE;
- }
- FX_FILESIZE GetSize() override { return (FX_FILESIZE)total_size_; };
-
- protected:
- const unsigned char* buffer_;
- size_t total_size_;
-};
-
-// A wrapper class to help test member functions of CPDF_Parser.
-class CPDF_TestParser : public CPDF_Parser {
- public:
- CPDF_TestParser() {}
- ~CPDF_TestParser() {}
-
- // Setup reading from a file and initial states.
- bool InitTestFromFile(const FX_CHAR* path) {
- IFX_FileRead* pFileAccess = FX_CreateFileRead(path);
- if (!pFileAccess)
- return false;
-
- // For the test file, the header is set at the beginning.
- m_pSyntax->InitParser(pFileAccess, 0);
- return true;
- }
-
- // Setup reading from a buffer and initial states.
- bool InitTestFromBuffer(const unsigned char* buffer, size_t len) {
- CFX_TestBufferRead* buffer_reader = new CFX_TestBufferRead(buffer, len);
-
- // For the test file, the header is set at the beginning.
- m_pSyntax->InitParser(buffer_reader, 0);
- return true;
- }
-
- private:
- // Add test cases here as private friend so that protected members in
- // CPDF_Parser can be accessed by test cases.
- // Need to access RebuildCrossRef.
- FRIEND_TEST(cpdf_parser, RebuildCrossRefCorrectly);
- FRIEND_TEST(cpdf_parser, RebuildCrossRefFailed);
- // Need to access LoadCrossRefV4.
- FRIEND_TEST(cpdf_parser, LoadCrossRefV4);
-};
-
-TEST(cpdf_parser, RebuildCrossRefCorrectly) {
- CPDF_TestParser parser;
- std::string test_file;
- ASSERT_TRUE(PathService::GetTestFilePath("parser_rebuildxref_correct.pdf",
- &test_file));
- ASSERT_TRUE(parser.InitTestFromFile(test_file.c_str())) << test_file;
-
- ASSERT_TRUE(parser.RebuildCrossRef());
- const FX_FILESIZE offsets[] = {0, 15, 61, 154, 296, 374, 450};
- const uint16_t versions[] = {0, 0, 2, 4, 6, 8, 0};
- for (size_t i = 0; i < FX_ArraySize(offsets); ++i)
- EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos);
- for (size_t i = 0; i < FX_ArraySize(versions); ++i)
- EXPECT_EQ(versions[i], parser.m_ObjectInfo[i].gennum);
-}
-
-TEST(cpdf_parser, RebuildCrossRefFailed) {
- CPDF_TestParser parser;
- std::string test_file;
- ASSERT_TRUE(PathService::GetTestFilePath(
- "parser_rebuildxref_error_notrailer.pdf", &test_file));
- ASSERT_TRUE(parser.InitTestFromFile(test_file.c_str())) << test_file;
-
- ASSERT_FALSE(parser.RebuildCrossRef());
-}
-
-TEST(cpdf_parser, LoadCrossRefV4) {
- {
- const unsigned char xref_table[] =
- "xref \n"
- "0 6 \n"
- "0000000003 65535 f \n"
- "0000000017 00000 n \n"
- "0000000081 00000 n \n"
- "0000000000 00007 f \n"
- "0000000331 00000 n \n"
- "0000000409 00000 n \n"
- "trail"; // Needed to end cross ref table reading.
- CPDF_TestParser parser;
- ASSERT_TRUE(
- parser.InitTestFromBuffer(xref_table, FX_ArraySize(xref_table)));
-
- ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, FALSE));
- const FX_FILESIZE offsets[] = {0, 17, 81, 0, 331, 409};
- const uint8_t types[] = {0, 1, 1, 0, 1, 1};
- for (size_t i = 0; i < FX_ArraySize(offsets); ++i) {
- EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos);
- EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type);
- }
- }
- {
- const unsigned char xref_table[] =
- "xref \n"
- "0 1 \n"
- "0000000000 65535 f \n"
- "3 1 \n"
- "0000025325 00000 n \n"
- "8 2 \n"
- "0000025518 00002 n \n"
- "0000025635 00000 n \n"
- "12 1 \n"
- "0000025777 00000 n \n"
- "trail"; // Needed to end cross ref table reading.
- CPDF_TestParser parser;
- ASSERT_TRUE(
- parser.InitTestFromBuffer(xref_table, FX_ArraySize(xref_table)));
-
- ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, FALSE));
- const FX_FILESIZE offsets[] = {0, 0, 0, 25325, 0, 0, 0,
- 0, 25518, 25635, 0, 0, 25777};
- const uint8_t types[] = {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1};
- for (size_t i = 0; i < FX_ArraySize(offsets); ++i) {
- EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos);
- EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type);
- }
- }
- {
- const unsigned char xref_table[] =
- "xref \n"
- "0 1 \n"
- "0000000000 65535 f \n"
- "3 1 \n"
- "0000025325 00000 n \n"
- "8 2 \n"
- "0000000000 65535 f \n"
- "0000025635 00000 n \n"
- "12 1 \n"
- "0000025777 00000 n \n"
- "trail"; // Needed to end cross ref table reading.
- CPDF_TestParser parser;
- ASSERT_TRUE(
- parser.InitTestFromBuffer(xref_table, FX_ArraySize(xref_table)));
-
- ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, FALSE));
- const FX_FILESIZE offsets[] = {0, 0, 0, 25325, 0, 0, 0,
- 0, 0, 25635, 0, 0, 25777};
- const uint8_t types[] = {0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1};
- for (size_t i = 0; i < FX_ArraySize(offsets); ++i) {
- EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos);
- EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type);
- }
- }
- {
- const unsigned char xref_table[] =
- "xref \n"
- "0 7 \n"
- "0000000002 65535 f \n"
- "0000000023 00000 n \n"
- "0000000003 65535 f \n"
- "0000000004 65535 f \n"
- "0000000000 65535 f \n"
- "0000000045 00000 n \n"
- "0000000179 00000 n \n"
- "trail"; // Needed to end cross ref table reading.
- CPDF_TestParser parser;
- ASSERT_TRUE(
- parser.InitTestFromBuffer(xref_table, FX_ArraySize(xref_table)));
-
- ASSERT_TRUE(parser.LoadCrossRefV4(0, 0, FALSE));
- const FX_FILESIZE offsets[] = {0, 23, 0, 0, 0, 45, 179};
- const uint8_t types[] = {0, 1, 0, 0, 0, 1, 1};
- for (size_t i = 0; i < FX_ArraySize(offsets); ++i) {
- EXPECT_EQ(offsets[i], parser.m_ObjectInfo[i].pos);
- EXPECT_EQ(types[i], parser.m_ObjectInfo[i].type);
- }
- }
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_reference.cpp b/core/fpdfapi/fpdf_parser/cpdf_reference.cpp
deleted file mode 100644
index 4f826dc86c..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_reference.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
-
-#include "core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h"
-#include "third_party/base/stl_util.h"
-
-CPDF_Reference::CPDF_Reference(CPDF_IndirectObjectHolder* pDoc, int objnum)
- : m_pObjList(pDoc), m_RefObjNum(objnum) {}
-
-CPDF_Reference::~CPDF_Reference() {}
-
-CPDF_Object::Type CPDF_Reference::GetType() const {
- return REFERENCE;
-}
-
-CFX_ByteString CPDF_Reference::GetString() const {
- CPDF_Object* obj = SafeGetDirect();
- return obj ? obj->GetString() : CFX_ByteString();
-}
-
-FX_FLOAT CPDF_Reference::GetNumber() const {
- CPDF_Object* obj = SafeGetDirect();
- return obj ? obj->GetNumber() : 0;
-}
-
-int CPDF_Reference::GetInteger() const {
- CPDF_Object* obj = SafeGetDirect();
- return obj ? obj->GetInteger() : 0;
-}
-
-CPDF_Dictionary* CPDF_Reference::GetDict() const {
- CPDF_Object* obj = SafeGetDirect();
- return obj ? obj->GetDict() : nullptr;
-}
-
-bool CPDF_Reference::IsReference() const {
- return true;
-}
-
-CPDF_Reference* CPDF_Reference::AsReference() {
- return this;
-}
-
-const CPDF_Reference* CPDF_Reference::AsReference() const {
- return this;
-}
-
-CPDF_Object* CPDF_Reference::Clone() const {
- return CloneObjectNonCyclic(false);
-}
-
-CPDF_Object* CPDF_Reference::CloneNonCyclic(
- bool bDirect,
- std::set<const CPDF_Object*>* pVisited) const {
- pVisited->insert(this);
- if (bDirect) {
- auto* pDirect = GetDirect();
- return pDirect && !pdfium::ContainsKey(*pVisited, pDirect)
- ? pDirect->CloneNonCyclic(true, pVisited)
- : nullptr;
- }
- return new CPDF_Reference(m_pObjList, m_RefObjNum);
-}
-
-CPDF_Object* CPDF_Reference::SafeGetDirect() const {
- CPDF_Object* obj = GetDirect();
- return (obj && !obj->IsReference()) ? obj : nullptr;
-}
-
-void CPDF_Reference::SetRef(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum) {
- m_pObjList = pDoc;
- m_RefObjNum = objnum;
-}
-
-CPDF_Object* CPDF_Reference::GetDirect() const {
- return m_pObjList ? m_pObjList->GetOrParseIndirectObject(m_RefObjNum)
- : nullptr;
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_reference.h b/core/fpdfapi/fpdf_parser/cpdf_reference.h
deleted file mode 100644
index 1322b97c6f..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_reference.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_REFERENCE_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_REFERENCE_H_
-
-#include <set>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-
-class CPDF_IndirectObjectHolder;
-
-class CPDF_Reference : public CPDF_Object {
- public:
- CPDF_Reference(CPDF_IndirectObjectHolder* pDoc, int objnum);
-
- // CPDF_Object.
- Type GetType() const override;
- CPDF_Object* Clone() const override;
- CPDF_Object* GetDirect() const override;
- CFX_ByteString GetString() const override;
- FX_FLOAT GetNumber() const override;
- int GetInteger() const override;
- CPDF_Dictionary* GetDict() const override;
- bool IsReference() const override;
- CPDF_Reference* AsReference() override;
- const CPDF_Reference* AsReference() const override;
-
- CPDF_IndirectObjectHolder* GetObjList() const { return m_pObjList; }
- uint32_t GetRefObjNum() const { return m_RefObjNum; }
-
- void SetRef(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum);
-
- protected:
- ~CPDF_Reference() override;
-
- CPDF_Object* CloneNonCyclic(
- bool bDirect,
- std::set<const CPDF_Object*>* pVisited) const override;
-
- CPDF_Object* SafeGetDirect() const;
-
- CPDF_IndirectObjectHolder* m_pObjList;
- uint32_t m_RefObjNum;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_REFERENCE_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_security_handler.cpp b/core/fpdfapi/fpdf_parser/cpdf_security_handler.cpp
deleted file mode 100644
index 2a57daab3e..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_security_handler.cpp
+++ /dev/null
@@ -1,699 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_security_handler.h"
-
-#include <time.h>
-
-#include "core/fdrm/crypto/fx_crypt.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_crypto_handler.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_parser.h"
-
-namespace {
-
-const uint8_t defpasscode[32] = {
- 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e,
- 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68,
- 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a};
-
-void CalcEncryptKey(CPDF_Dictionary* pEncrypt,
- const uint8_t* password,
- uint32_t pass_size,
- uint8_t* key,
- int keylen,
- FX_BOOL bIgnoreMeta,
- CPDF_Array* pIdArray) {
- int revision = pEncrypt->GetIntegerFor("R");
- uint8_t passcode[32];
- for (uint32_t i = 0; i < 32; i++) {
- passcode[i] = i < pass_size ? password[i] : defpasscode[i - pass_size];
- }
- uint8_t md5[100];
- CRYPT_MD5Start(md5);
- CRYPT_MD5Update(md5, passcode, 32);
- CFX_ByteString okey = pEncrypt->GetStringFor("O");
- CRYPT_MD5Update(md5, (uint8_t*)okey.c_str(), okey.GetLength());
- uint32_t perm = pEncrypt->GetIntegerFor("P");
- CRYPT_MD5Update(md5, (uint8_t*)&perm, 4);
- if (pIdArray) {
- CFX_ByteString id = pIdArray->GetStringAt(0);
- CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
- }
- if (!bIgnoreMeta && revision >= 3 &&
- !pEncrypt->GetIntegerFor("EncryptMetadata", 1)) {
- uint32_t tag = (uint32_t)-1;
- CRYPT_MD5Update(md5, (uint8_t*)&tag, 4);
- }
- uint8_t digest[16];
- CRYPT_MD5Finish(md5, digest);
- uint32_t copy_len = keylen;
- if (copy_len > sizeof(digest)) {
- copy_len = sizeof(digest);
- }
- if (revision >= 3) {
- for (int i = 0; i < 50; i++) {
- CRYPT_MD5Generate(digest, copy_len, digest);
- }
- }
- FXSYS_memset(key, 0, keylen);
- FXSYS_memcpy(key, digest, copy_len);
-}
-
-} // namespace
-
-CPDF_SecurityHandler::CPDF_SecurityHandler()
- : m_Version(0),
- m_Revision(0),
- m_pParser(nullptr),
- m_pEncryptDict(nullptr),
- m_Permissions(0),
- m_Cipher(FXCIPHER_NONE),
- m_KeyLen(0),
- m_bOwnerUnlocked(false) {}
-
-CPDF_SecurityHandler::~CPDF_SecurityHandler() {}
-
-CPDF_CryptoHandler* CPDF_SecurityHandler::CreateCryptoHandler() {
- return new CPDF_CryptoHandler;
-}
-
-FX_BOOL CPDF_SecurityHandler::OnInit(CPDF_Parser* pParser,
- CPDF_Dictionary* pEncryptDict) {
- m_pParser = pParser;
- if (!LoadDict(pEncryptDict)) {
- return FALSE;
- }
- if (m_Cipher == FXCIPHER_NONE) {
- return TRUE;
- }
- return CheckSecurity(m_KeyLen);
-}
-
-FX_BOOL CPDF_SecurityHandler::CheckSecurity(int32_t key_len) {
- CFX_ByteString password = m_pParser->GetPassword();
- if (!password.IsEmpty() &&
- CheckPassword(password.raw_str(), password.GetLength(), TRUE,
- m_EncryptKey, key_len)) {
- m_bOwnerUnlocked = true;
- return TRUE;
- }
- return CheckPassword(password.raw_str(), password.GetLength(), FALSE,
- m_EncryptKey, key_len);
-}
-
-uint32_t CPDF_SecurityHandler::GetPermissions() {
- return m_bOwnerUnlocked ? 0xFFFFFFFF : m_Permissions;
-}
-
-static FX_BOOL LoadCryptInfo(CPDF_Dictionary* pEncryptDict,
- const CFX_ByteString& name,
- int& cipher,
- int& keylen) {
- int Version = pEncryptDict->GetIntegerFor("V");
- cipher = FXCIPHER_RC4;
- keylen = 0;
- if (Version >= 4) {
- CPDF_Dictionary* pCryptFilters = pEncryptDict->GetDictFor("CF");
- if (!pCryptFilters) {
- return FALSE;
- }
- if (name == "Identity") {
- cipher = FXCIPHER_NONE;
- } else {
- CPDF_Dictionary* pDefFilter = pCryptFilters->GetDictFor(name);
- if (!pDefFilter) {
- return FALSE;
- }
- int nKeyBits = 0;
- if (Version == 4) {
- nKeyBits = pDefFilter->GetIntegerFor("Length", 0);
- if (nKeyBits == 0) {
- nKeyBits = pEncryptDict->GetIntegerFor("Length", 128);
- }
- } else {
- nKeyBits = pEncryptDict->GetIntegerFor("Length", 256);
- }
- if (nKeyBits < 40) {
- nKeyBits *= 8;
- }
- keylen = nKeyBits / 8;
- CFX_ByteString cipher_name = pDefFilter->GetStringFor("CFM");
- if (cipher_name == "AESV2" || cipher_name == "AESV3") {
- cipher = FXCIPHER_AES;
- }
- }
- } else {
- keylen = Version > 1 ? pEncryptDict->GetIntegerFor("Length", 40) / 8 : 5;
- }
- if (keylen > 32 || keylen < 0) {
- return FALSE;
- }
- return TRUE;
-}
-
-FX_BOOL CPDF_SecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict) {
- m_pEncryptDict = pEncryptDict;
- m_Version = pEncryptDict->GetIntegerFor("V");
- m_Revision = pEncryptDict->GetIntegerFor("R");
- m_Permissions = pEncryptDict->GetIntegerFor("P", -1);
- if (m_Version < 4)
- return LoadCryptInfo(pEncryptDict, CFX_ByteString(), m_Cipher, m_KeyLen);
-
- CFX_ByteString stmf_name = pEncryptDict->GetStringFor("StmF");
- CFX_ByteString strf_name = pEncryptDict->GetStringFor("StrF");
- if (stmf_name != strf_name)
- return FALSE;
-
- return LoadCryptInfo(pEncryptDict, strf_name, m_Cipher, m_KeyLen);
-}
-
-FX_BOOL CPDF_SecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict,
- uint32_t type,
- int& cipher,
- int& key_len) {
- m_pEncryptDict = pEncryptDict;
- m_Version = pEncryptDict->GetIntegerFor("V");
- m_Revision = pEncryptDict->GetIntegerFor("R");
- m_Permissions = pEncryptDict->GetIntegerFor("P", -1);
-
- CFX_ByteString strf_name;
- CFX_ByteString stmf_name;
- if (m_Version >= 4) {
- stmf_name = pEncryptDict->GetStringFor("StmF");
- strf_name = pEncryptDict->GetStringFor("StrF");
- if (stmf_name != strf_name)
- return FALSE;
- }
- if (!LoadCryptInfo(pEncryptDict, strf_name, cipher, key_len))
- return FALSE;
-
- m_Cipher = cipher;
- m_KeyLen = key_len;
- return TRUE;
-}
-
-FX_BOOL CPDF_SecurityHandler::GetCryptInfo(int& cipher,
- const uint8_t*& buffer,
- int& keylen) {
- cipher = m_Cipher;
- buffer = m_EncryptKey;
- keylen = m_KeyLen;
- return TRUE;
-}
-#define FX_GET_32WORD(n, b, i) \
- { \
- (n) = (uint32_t)( \
- ((uint64_t)(b)[(i)] << 24) | ((uint64_t)(b)[(i) + 1] << 16) | \
- ((uint64_t)(b)[(i) + 2] << 8) | ((uint64_t)(b)[(i) + 3])); \
- }
-int BigOrder64BitsMod3(uint8_t* data) {
- uint64_t ret = 0;
- for (int i = 0; i < 4; ++i) {
- uint32_t value;
- FX_GET_32WORD(value, data, 4 * i);
- ret <<= 32;
- ret |= value;
- ret %= 3;
- }
- return (int)ret;
-}
-void Revision6_Hash(const uint8_t* password,
- uint32_t size,
- const uint8_t* salt,
- const uint8_t* vector,
- uint8_t* hash) {
- int iBlockSize = 32;
- uint8_t sha[128];
- CRYPT_SHA256Start(sha);
- CRYPT_SHA256Update(sha, password, size);
- CRYPT_SHA256Update(sha, salt, 8);
- if (vector) {
- CRYPT_SHA256Update(sha, vector, 48);
- }
- uint8_t digest[32];
- CRYPT_SHA256Finish(sha, digest);
- CFX_ByteTextBuf buf;
- uint8_t* input = digest;
- uint8_t* key = input;
- uint8_t* iv = input + 16;
- uint8_t* E = buf.GetBuffer();
- int iBufLen = buf.GetLength();
- CFX_ByteTextBuf interDigest;
- int i = 0;
- uint8_t* aes = FX_Alloc(uint8_t, 2048);
- while (i < 64 || i < E[iBufLen - 1] + 32) {
- int iRoundSize = size + iBlockSize;
- if (vector) {
- iRoundSize += 48;
- }
- iBufLen = iRoundSize * 64;
- buf.EstimateSize(iBufLen);
- E = buf.GetBuffer();
- CFX_ByteTextBuf content;
- for (int j = 0; j < 64; ++j) {
- content.AppendBlock(password, size);
- content.AppendBlock(input, iBlockSize);
- if (vector) {
- content.AppendBlock(vector, 48);
- }
- }
- CRYPT_AESSetKey(aes, 16, key, 16, TRUE);
- CRYPT_AESSetIV(aes, iv);
- CRYPT_AESEncrypt(aes, E, content.GetBuffer(), iBufLen);
- int iHash = 0;
- switch (BigOrder64BitsMod3(E)) {
- case 0:
- iHash = 0;
- iBlockSize = 32;
- break;
- case 1:
- iHash = 1;
- iBlockSize = 48;
- break;
- default:
- iHash = 2;
- iBlockSize = 64;
- break;
- }
- interDigest.EstimateSize(iBlockSize);
- input = interDigest.GetBuffer();
- if (iHash == 0) {
- CRYPT_SHA256Generate(E, iBufLen, input);
- } else if (iHash == 1) {
- CRYPT_SHA384Generate(E, iBufLen, input);
- } else if (iHash == 2) {
- CRYPT_SHA512Generate(E, iBufLen, input);
- }
- key = input;
- iv = input + 16;
- ++i;
- }
- FX_Free(aes);
- if (hash) {
- FXSYS_memcpy(hash, input, 32);
- }
-}
-FX_BOOL CPDF_SecurityHandler::AES256_CheckPassword(const uint8_t* password,
- uint32_t size,
- FX_BOOL bOwner,
- uint8_t* key) {
- CFX_ByteString okey =
- m_pEncryptDict ? m_pEncryptDict->GetStringFor("O") : CFX_ByteString();
- if (okey.GetLength() < 48) {
- return FALSE;
- }
- CFX_ByteString ukey =
- m_pEncryptDict ? m_pEncryptDict->GetStringFor("U") : CFX_ByteString();
- if (ukey.GetLength() < 48) {
- return FALSE;
- }
- const uint8_t* pkey = (bOwner ? okey : ukey).raw_str();
- uint8_t sha[128];
- uint8_t digest[32];
- if (m_Revision >= 6) {
- Revision6_Hash(password, size, (const uint8_t*)pkey + 32,
- bOwner ? ukey.raw_str() : nullptr, digest);
- } else {
- CRYPT_SHA256Start(sha);
- CRYPT_SHA256Update(sha, password, size);
- CRYPT_SHA256Update(sha, pkey + 32, 8);
- if (bOwner) {
- CRYPT_SHA256Update(sha, ukey.raw_str(), 48);
- }
- CRYPT_SHA256Finish(sha, digest);
- }
- if (FXSYS_memcmp(digest, pkey, 32) != 0) {
- return FALSE;
- }
- if (!key) {
- return TRUE;
- }
- if (m_Revision >= 6) {
- Revision6_Hash(password, size, (const uint8_t*)pkey + 40,
- bOwner ? ukey.raw_str() : nullptr, digest);
- } else {
- CRYPT_SHA256Start(sha);
- CRYPT_SHA256Update(sha, password, size);
- CRYPT_SHA256Update(sha, pkey + 40, 8);
- if (bOwner) {
- CRYPT_SHA256Update(sha, ukey.raw_str(), 48);
- }
- CRYPT_SHA256Finish(sha, digest);
- }
- CFX_ByteString ekey = m_pEncryptDict
- ? m_pEncryptDict->GetStringFor(bOwner ? "OE" : "UE")
- : CFX_ByteString();
- if (ekey.GetLength() < 32) {
- return FALSE;
- }
- uint8_t* aes = FX_Alloc(uint8_t, 2048);
- CRYPT_AESSetKey(aes, 16, digest, 32, FALSE);
- uint8_t iv[16];
- FXSYS_memset(iv, 0, 16);
- CRYPT_AESSetIV(aes, iv);
- CRYPT_AESDecrypt(aes, key, ekey.raw_str(), 32);
- CRYPT_AESSetKey(aes, 16, key, 32, FALSE);
- CRYPT_AESSetIV(aes, iv);
- CFX_ByteString perms = m_pEncryptDict->GetStringFor("Perms");
- if (perms.IsEmpty()) {
- return FALSE;
- }
- uint8_t perms_buf[16];
- FXSYS_memset(perms_buf, 0, sizeof(perms_buf));
- uint32_t copy_len = sizeof(perms_buf);
- if (copy_len > (uint32_t)perms.GetLength()) {
- copy_len = perms.GetLength();
- }
- FXSYS_memcpy(perms_buf, perms.raw_str(), copy_len);
- uint8_t buf[16];
- CRYPT_AESDecrypt(aes, buf, perms_buf, 16);
- FX_Free(aes);
- if (buf[9] != 'a' || buf[10] != 'd' || buf[11] != 'b') {
- return FALSE;
- }
- if (FXDWORD_GET_LSBFIRST(buf) != m_Permissions) {
- return FALSE;
- }
- if ((buf[8] == 'T' && !IsMetadataEncrypted()) ||
- (buf[8] == 'F' && IsMetadataEncrypted())) {
- return FALSE;
- }
- return TRUE;
-}
-
-int CPDF_SecurityHandler::CheckPassword(const uint8_t* password,
- uint32_t size,
- FX_BOOL bOwner,
- uint8_t* key,
- int32_t key_len) {
- if (m_Revision >= 5) {
- return AES256_CheckPassword(password, size, bOwner, key);
- }
- uint8_t keybuf[32];
- if (!key) {
- key = keybuf;
- }
- if (bOwner) {
- return CheckOwnerPassword(password, size, key, key_len);
- }
- return CheckUserPassword(password, size, FALSE, key, key_len) ||
- CheckUserPassword(password, size, TRUE, key, key_len);
-}
-FX_BOOL CPDF_SecurityHandler::CheckUserPassword(const uint8_t* password,
- uint32_t pass_size,
- FX_BOOL bIgnoreEncryptMeta,
- uint8_t* key,
- int32_t key_len) {
- CalcEncryptKey(m_pEncryptDict, password, pass_size, key, key_len,
- bIgnoreEncryptMeta, m_pParser->GetIDArray());
- CFX_ByteString ukey =
- m_pEncryptDict ? m_pEncryptDict->GetStringFor("U") : CFX_ByteString();
- if (ukey.GetLength() < 16) {
- return FALSE;
- }
- uint8_t ukeybuf[32];
- if (m_Revision == 2) {
- FXSYS_memcpy(ukeybuf, defpasscode, 32);
- CRYPT_ArcFourCryptBlock(ukeybuf, 32, key, key_len);
- } else {
- uint8_t test[32], tmpkey[32];
- uint32_t copy_len = sizeof(test);
- if (copy_len > (uint32_t)ukey.GetLength()) {
- copy_len = ukey.GetLength();
- }
- FXSYS_memset(test, 0, sizeof(test));
- FXSYS_memset(tmpkey, 0, sizeof(tmpkey));
- FXSYS_memcpy(test, ukey.c_str(), copy_len);
- for (int32_t i = 19; i >= 0; i--) {
- for (int j = 0; j < key_len; j++)
- tmpkey[j] = key[j] ^ static_cast<uint8_t>(i);
- CRYPT_ArcFourCryptBlock(test, 32, tmpkey, key_len);
- }
- uint8_t md5[100];
- CRYPT_MD5Start(md5);
- CRYPT_MD5Update(md5, defpasscode, 32);
- CPDF_Array* pIdArray = m_pParser->GetIDArray();
- if (pIdArray) {
- CFX_ByteString id = pIdArray->GetStringAt(0);
- CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
- }
- CRYPT_MD5Finish(md5, ukeybuf);
- return FXSYS_memcmp(test, ukeybuf, 16) == 0;
- }
- if (FXSYS_memcmp((void*)ukey.c_str(), ukeybuf, 16) == 0) {
- return TRUE;
- }
- return FALSE;
-}
-CFX_ByteString CPDF_SecurityHandler::GetUserPassword(const uint8_t* owner_pass,
- uint32_t pass_size,
- int32_t key_len) {
- CFX_ByteString okey = m_pEncryptDict->GetStringFor("O");
- uint8_t passcode[32];
- for (uint32_t i = 0; i < 32; i++) {
- passcode[i] = i < pass_size ? owner_pass[i] : defpasscode[i - pass_size];
- }
- uint8_t digest[16];
- CRYPT_MD5Generate(passcode, 32, digest);
- if (m_Revision >= 3) {
- for (uint32_t i = 0; i < 50; i++) {
- CRYPT_MD5Generate(digest, 16, digest);
- }
- }
- uint8_t enckey[32];
- FXSYS_memset(enckey, 0, sizeof(enckey));
- uint32_t copy_len = key_len;
- if (copy_len > sizeof(digest)) {
- copy_len = sizeof(digest);
- }
- FXSYS_memcpy(enckey, digest, copy_len);
- int okeylen = okey.GetLength();
- if (okeylen > 32) {
- okeylen = 32;
- }
- uint8_t okeybuf[64];
- FXSYS_memset(okeybuf, 0, sizeof(okeybuf));
- FXSYS_memcpy(okeybuf, okey.c_str(), okeylen);
- if (m_Revision == 2) {
- CRYPT_ArcFourCryptBlock(okeybuf, okeylen, enckey, key_len);
- } else {
- for (int32_t i = 19; i >= 0; i--) {
- uint8_t tempkey[32];
- FXSYS_memset(tempkey, 0, sizeof(tempkey));
- for (int j = 0; j < m_KeyLen; j++)
- tempkey[j] = enckey[j] ^ static_cast<uint8_t>(i);
- CRYPT_ArcFourCryptBlock(okeybuf, okeylen, tempkey, key_len);
- }
- }
- int len = 32;
- while (len && defpasscode[len - 1] == okeybuf[len - 1]) {
- len--;
- }
- return CFX_ByteString(okeybuf, len);
-}
-FX_BOOL CPDF_SecurityHandler::CheckOwnerPassword(const uint8_t* password,
- uint32_t pass_size,
- uint8_t* key,
- int32_t key_len) {
- CFX_ByteString user_pass = GetUserPassword(password, pass_size, key_len);
- if (CheckUserPassword(user_pass.raw_str(), user_pass.GetLength(), FALSE, key,
- key_len)) {
- return TRUE;
- }
- return CheckUserPassword(user_pass.raw_str(), user_pass.GetLength(), TRUE,
- key, key_len);
-}
-
-bool CPDF_SecurityHandler::IsMetadataEncrypted() const {
- return m_pEncryptDict->GetBooleanFor("EncryptMetadata", true);
-}
-
-void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
- CPDF_Array* pIdArray,
- const uint8_t* user_pass,
- uint32_t user_size,
- const uint8_t* owner_pass,
- uint32_t owner_size,
- FX_BOOL bDefault,
- uint32_t type) {
- int cipher = 0, key_len = 0;
- if (!LoadDict(pEncryptDict, type, cipher, key_len)) {
- return;
- }
- if (bDefault && (!owner_pass || owner_size == 0)) {
- owner_pass = user_pass;
- owner_size = user_size;
- }
- if (m_Revision >= 5) {
- int t = (int)time(nullptr);
- uint8_t sha[128];
- CRYPT_SHA256Start(sha);
- CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t);
- CRYPT_SHA256Update(sha, m_EncryptKey, 32);
- CRYPT_SHA256Update(sha, (uint8_t*)"there", 5);
- CRYPT_SHA256Finish(sha, m_EncryptKey);
- AES256_SetPassword(pEncryptDict, user_pass, user_size, FALSE, m_EncryptKey);
- if (bDefault) {
- AES256_SetPassword(pEncryptDict, owner_pass, owner_size, TRUE,
- m_EncryptKey);
- AES256_SetPerms(pEncryptDict, m_Permissions,
- pEncryptDict->GetBooleanFor("EncryptMetadata", true),
- m_EncryptKey);
- }
- return;
- }
- if (bDefault) {
- uint8_t passcode[32];
- for (uint32_t i = 0; i < 32; i++) {
- passcode[i] =
- i < owner_size ? owner_pass[i] : defpasscode[i - owner_size];
- }
- uint8_t digest[16];
- CRYPT_MD5Generate(passcode, 32, digest);
- if (m_Revision >= 3) {
- for (uint32_t i = 0; i < 50; i++)
- CRYPT_MD5Generate(digest, 16, digest);
- }
- uint8_t enckey[32];
- FXSYS_memcpy(enckey, digest, key_len);
- for (uint32_t i = 0; i < 32; i++) {
- passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size];
- }
- CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len);
- uint8_t tempkey[32];
- if (m_Revision >= 3) {
- for (uint8_t i = 1; i <= 19; i++) {
- for (int j = 0; j < key_len; j++)
- tempkey[j] = enckey[j] ^ i;
- CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len);
- }
- }
- pEncryptDict->SetStringFor("O", CFX_ByteString(passcode, 32));
- }
- CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey,
- key_len, FALSE, pIdArray);
- if (m_Revision < 3) {
- uint8_t tempbuf[32];
- FXSYS_memcpy(tempbuf, defpasscode, 32);
- CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len);
- pEncryptDict->SetStringFor("U", CFX_ByteString(tempbuf, 32));
- } else {
- uint8_t md5[100];
- CRYPT_MD5Start(md5);
- CRYPT_MD5Update(md5, defpasscode, 32);
- if (pIdArray) {
- CFX_ByteString id = pIdArray->GetStringAt(0);
- CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
- }
- uint8_t digest[32];
- CRYPT_MD5Finish(md5, digest);
- CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len);
- uint8_t tempkey[32];
- for (uint8_t i = 1; i <= 19; i++) {
- for (int j = 0; j < key_len; j++) {
- tempkey[j] = m_EncryptKey[j] ^ i;
- }
- CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len);
- }
- CRYPT_MD5Generate(digest, 16, digest + 16);
- pEncryptDict->SetStringFor("U", CFX_ByteString(digest, 32));
- }
-}
-void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
- CPDF_Array* pIdArray,
- const uint8_t* user_pass,
- uint32_t user_size,
- const uint8_t* owner_pass,
- uint32_t owner_size,
- uint32_t type) {
- OnCreate(pEncryptDict, pIdArray, user_pass, user_size, owner_pass, owner_size,
- TRUE, type);
-}
-void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
- CPDF_Array* pIdArray,
- const uint8_t* user_pass,
- uint32_t user_size,
- uint32_t type) {
- OnCreate(pEncryptDict, pIdArray, user_pass, user_size, nullptr, 0, FALSE,
- type);
-}
-void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict,
- const uint8_t* password,
- uint32_t size,
- FX_BOOL bOwner,
- const uint8_t* key) {
- uint8_t sha[128];
- CRYPT_SHA1Start(sha);
- CRYPT_SHA1Update(sha, key, 32);
- CRYPT_SHA1Update(sha, (uint8_t*)"hello", 5);
- uint8_t digest[20];
- CRYPT_SHA1Finish(sha, digest);
- CFX_ByteString ukey = pEncryptDict->GetStringFor("U");
- uint8_t digest1[48];
- if (m_Revision >= 6) {
- Revision6_Hash(password, size, digest, bOwner ? ukey.raw_str() : nullptr,
- digest1);
- } else {
- CRYPT_SHA256Start(sha);
- CRYPT_SHA256Update(sha, password, size);
- CRYPT_SHA256Update(sha, digest, 8);
- if (bOwner) {
- CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength());
- }
- CRYPT_SHA256Finish(sha, digest1);
- }
- FXSYS_memcpy(digest1 + 32, digest, 16);
- pEncryptDict->SetStringFor(bOwner ? "O" : "U", CFX_ByteString(digest1, 48));
- if (m_Revision >= 6) {
- Revision6_Hash(password, size, digest + 8,
- bOwner ? ukey.raw_str() : nullptr, digest1);
- } else {
- CRYPT_SHA256Start(sha);
- CRYPT_SHA256Update(sha, password, size);
- CRYPT_SHA256Update(sha, digest + 8, 8);
- if (bOwner) {
- CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength());
- }
- CRYPT_SHA256Finish(sha, digest1);
- }
- uint8_t* aes = FX_Alloc(uint8_t, 2048);
- CRYPT_AESSetKey(aes, 16, digest1, 32, TRUE);
- uint8_t iv[16];
- FXSYS_memset(iv, 0, 16);
- CRYPT_AESSetIV(aes, iv);
- CRYPT_AESEncrypt(aes, digest1, key, 32);
- FX_Free(aes);
- pEncryptDict->SetStringFor(bOwner ? "OE" : "UE", CFX_ByteString(digest1, 32));
-}
-void CPDF_SecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict,
- uint32_t permissions,
- FX_BOOL bEncryptMetadata,
- const uint8_t* key) {
- uint8_t buf[16];
- buf[0] = (uint8_t)permissions;
- buf[1] = (uint8_t)(permissions >> 8);
- buf[2] = (uint8_t)(permissions >> 16);
- buf[3] = (uint8_t)(permissions >> 24);
- buf[4] = 0xff;
- buf[5] = 0xff;
- buf[6] = 0xff;
- buf[7] = 0xff;
- buf[8] = bEncryptMetadata ? 'T' : 'F';
- buf[9] = 'a';
- buf[10] = 'd';
- buf[11] = 'b';
- uint8_t* aes = FX_Alloc(uint8_t, 2048);
- CRYPT_AESSetKey(aes, 16, key, 32, TRUE);
- uint8_t iv[16], buf1[16];
- FXSYS_memset(iv, 0, 16);
- CRYPT_AESSetIV(aes, iv);
- CRYPT_AESEncrypt(aes, buf1, buf, 16);
- FX_Free(aes);
- pEncryptDict->SetStringFor("Perms", CFX_ByteString(buf1, 16));
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_security_handler.h b/core/fpdfapi/fpdf_parser/cpdf_security_handler.h
deleted file mode 100644
index 33c4c0c17d..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_security_handler.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_SECURITY_HANDLER_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_SECURITY_HANDLER_H_
-
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-
-#define FXCIPHER_NONE 0
-#define FXCIPHER_RC4 1
-#define FXCIPHER_AES 2
-#define FXCIPHER_AES2 3
-
-#define PDF_ENCRYPT_CONTENT 0
-
-class CPDF_Array;
-class CPDF_CryptoHandler;
-class CPDF_Dictionary;
-class CPDF_Parser;
-
-class CPDF_SecurityHandler {
- public:
- CPDF_SecurityHandler();
- ~CPDF_SecurityHandler();
-
- FX_BOOL OnInit(CPDF_Parser* pParser, CPDF_Dictionary* pEncryptDict);
- uint32_t GetPermissions();
- FX_BOOL GetCryptInfo(int& cipher, const uint8_t*& buffer, int& keylen);
- bool IsMetadataEncrypted() const;
- CPDF_CryptoHandler* CreateCryptoHandler();
-
- void OnCreate(CPDF_Dictionary* pEncryptDict,
- CPDF_Array* pIdArray,
- const uint8_t* user_pass,
- uint32_t user_size,
- const uint8_t* owner_pass,
- uint32_t owner_size,
- uint32_t type = PDF_ENCRYPT_CONTENT);
-
- void OnCreate(CPDF_Dictionary* pEncryptDict,
- CPDF_Array* pIdArray,
- const uint8_t* user_pass,
- uint32_t user_size,
- uint32_t type = PDF_ENCRYPT_CONTENT);
-
- CFX_ByteString GetUserPassword(const uint8_t* owner_pass,
- uint32_t pass_size,
- int32_t key_len);
- int CheckPassword(const uint8_t* password,
- uint32_t pass_size,
- FX_BOOL bOwner,
- uint8_t* key,
- int key_len);
-
- private:
- FX_BOOL LoadDict(CPDF_Dictionary* pEncryptDict);
- FX_BOOL LoadDict(CPDF_Dictionary* pEncryptDict,
- uint32_t type,
- int& cipher,
- int& key_len);
-
- FX_BOOL CheckUserPassword(const uint8_t* password,
- uint32_t pass_size,
- FX_BOOL bIgnoreEncryptMeta,
- uint8_t* key,
- int32_t key_len);
-
- FX_BOOL CheckOwnerPassword(const uint8_t* password,
- uint32_t pass_size,
- uint8_t* key,
- int32_t key_len);
- FX_BOOL AES256_CheckPassword(const uint8_t* password,
- uint32_t size,
- FX_BOOL bOwner,
- uint8_t* key);
- void AES256_SetPassword(CPDF_Dictionary* pEncryptDict,
- const uint8_t* password,
- uint32_t size,
- FX_BOOL bOwner,
- const uint8_t* key);
- void AES256_SetPerms(CPDF_Dictionary* pEncryptDict,
- uint32_t permission,
- FX_BOOL bEncryptMetadata,
- const uint8_t* key);
- void OnCreate(CPDF_Dictionary* pEncryptDict,
- CPDF_Array* pIdArray,
- const uint8_t* user_pass,
- uint32_t user_size,
- const uint8_t* owner_pass,
- uint32_t owner_size,
- FX_BOOL bDefault,
- uint32_t type);
- FX_BOOL CheckSecurity(int32_t key_len);
-
- int m_Version;
- int m_Revision;
- CPDF_Parser* m_pParser;
- CPDF_Dictionary* m_pEncryptDict;
- uint32_t m_Permissions;
- int m_Cipher;
- uint8_t m_EncryptKey[32];
- int m_KeyLen;
- bool m_bOwnerUnlocked;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_SECURITY_HANDLER_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_security_handler_embeddertest.cpp b/core/fpdfapi/fpdf_parser/cpdf_security_handler_embeddertest.cpp
deleted file mode 100644
index 37b6d8fc33..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_security_handler_embeddertest.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/embedder_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-class CPDFSecurityHandlerEmbeddertest : public EmbedderTest {};
-
-TEST_F(CPDFSecurityHandlerEmbeddertest, Unencrypted) {
- ASSERT_TRUE(OpenDocument("about_blank.pdf"));
- EXPECT_EQ(0xFFFFFFFF, FPDF_GetDocPermissions(document()));
-}
-
-TEST_F(CPDFSecurityHandlerEmbeddertest, UnencryptedWithPassword) {
- ASSERT_TRUE(OpenDocument("about_blank.pdf", "foobar"));
- EXPECT_EQ(0xFFFFFFFF, FPDF_GetDocPermissions(document()));
-}
-
-TEST_F(CPDFSecurityHandlerEmbeddertest, NoPassword) {
- EXPECT_FALSE(OpenDocument("encrypted.pdf"));
-}
-
-TEST_F(CPDFSecurityHandlerEmbeddertest, UserPassword) {
- ASSERT_TRUE(OpenDocument("encrypted.pdf", "1234"));
- EXPECT_EQ(0xFFFFF2C0, FPDF_GetDocPermissions(document()));
-}
-
-TEST_F(CPDFSecurityHandlerEmbeddertest, OwnerPassword) {
- ASSERT_TRUE(OpenDocument("encrypted.pdf", "5678"));
- EXPECT_EQ(0xFFFFFFFC, FPDF_GetDocPermissions(document()));
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_simple_parser.cpp b/core/fpdfapi/fpdf_parser/cpdf_simple_parser.cpp
deleted file mode 100644
index 821cd1b75b..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_simple_parser.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h"
-
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h"
-
-CPDF_SimpleParser::CPDF_SimpleParser(const uint8_t* pData, uint32_t dwSize)
- : m_pData(pData), m_dwSize(dwSize), m_dwCurPos(0) {}
-
-CPDF_SimpleParser::CPDF_SimpleParser(const CFX_ByteStringC& str)
- : m_pData(str.raw_str()), m_dwSize(str.GetLength()), m_dwCurPos(0) {}
-
-void CPDF_SimpleParser::ParseWord(const uint8_t*& pStart, uint32_t& dwSize) {
- pStart = nullptr;
- dwSize = 0;
- uint8_t ch;
- while (1) {
- if (m_dwSize <= m_dwCurPos)
- return;
- ch = m_pData[m_dwCurPos++];
- while (PDFCharIsWhitespace(ch)) {
- if (m_dwSize <= m_dwCurPos)
- return;
- ch = m_pData[m_dwCurPos++];
- }
-
- if (ch != '%')
- break;
-
- while (1) {
- if (m_dwSize <= m_dwCurPos)
- return;
- ch = m_pData[m_dwCurPos++];
- if (PDFCharIsLineEnding(ch))
- break;
- }
- }
-
- uint32_t start_pos = m_dwCurPos - 1;
- pStart = m_pData + start_pos;
- if (PDFCharIsDelimiter(ch)) {
- if (ch == '/') {
- while (1) {
- if (m_dwSize <= m_dwCurPos)
- return;
- ch = m_pData[m_dwCurPos++];
- if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) {
- m_dwCurPos--;
- dwSize = m_dwCurPos - start_pos;
- return;
- }
- }
- } else {
- dwSize = 1;
- if (ch == '<') {
- if (m_dwSize <= m_dwCurPos)
- return;
- ch = m_pData[m_dwCurPos++];
- if (ch == '<')
- dwSize = 2;
- else
- m_dwCurPos--;
- } else if (ch == '>') {
- if (m_dwSize <= m_dwCurPos)
- return;
- ch = m_pData[m_dwCurPos++];
- if (ch == '>')
- dwSize = 2;
- else
- m_dwCurPos--;
- }
- }
- return;
- }
-
- dwSize = 1;
- while (1) {
- if (m_dwSize <= m_dwCurPos)
- return;
- ch = m_pData[m_dwCurPos++];
-
- if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) {
- m_dwCurPos--;
- break;
- }
- dwSize++;
- }
-}
-
-CFX_ByteStringC CPDF_SimpleParser::GetWord() {
- const uint8_t* pStart;
- uint32_t dwSize;
- ParseWord(pStart, dwSize);
- if (dwSize == 1 && pStart[0] == '<') {
- while (m_dwCurPos < m_dwSize && m_pData[m_dwCurPos] != '>') {
- m_dwCurPos++;
- }
- if (m_dwCurPos < m_dwSize) {
- m_dwCurPos++;
- }
- return CFX_ByteStringC(pStart,
- (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData)));
- }
- if (dwSize == 1 && pStart[0] == '(') {
- int level = 1;
- while (m_dwCurPos < m_dwSize) {
- if (m_pData[m_dwCurPos] == ')') {
- level--;
- if (level == 0) {
- break;
- }
- }
- if (m_pData[m_dwCurPos] == '\\') {
- if (m_dwSize <= m_dwCurPos) {
- break;
- }
- m_dwCurPos++;
- } else if (m_pData[m_dwCurPos] == '(') {
- level++;
- }
- if (m_dwSize <= m_dwCurPos) {
- break;
- }
- m_dwCurPos++;
- }
- if (m_dwCurPos < m_dwSize) {
- m_dwCurPos++;
- }
- return CFX_ByteStringC(pStart,
- (FX_STRSIZE)(m_dwCurPos - (pStart - m_pData)));
- }
- return CFX_ByteStringC(pStart, dwSize);
-}
-
-bool CPDF_SimpleParser::FindTagParamFromStart(const CFX_ByteStringC& token,
- int nParams) {
- nParams++;
- uint32_t* pBuf = FX_Alloc(uint32_t, nParams);
- int buf_index = 0;
- int buf_count = 0;
- m_dwCurPos = 0;
- while (1) {
- pBuf[buf_index++] = m_dwCurPos;
- if (buf_index == nParams) {
- buf_index = 0;
- }
- buf_count++;
- if (buf_count > nParams) {
- buf_count = nParams;
- }
- CFX_ByteStringC word = GetWord();
- if (word.IsEmpty()) {
- FX_Free(pBuf);
- return false;
- }
- if (word == token) {
- if (buf_count < nParams) {
- continue;
- }
- m_dwCurPos = pBuf[buf_index];
- FX_Free(pBuf);
- return true;
- }
- }
- return false;
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_simple_parser.h b/core/fpdfapi/fpdf_parser/cpdf_simple_parser.h
deleted file mode 100644
index d23182dcb8..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_simple_parser.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_SIMPLE_PARSER_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_SIMPLE_PARSER_H_
-
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-
-class CPDF_SimpleParser {
- public:
- CPDF_SimpleParser(const uint8_t* pData, uint32_t dwSize);
- CPDF_SimpleParser(const CFX_ByteStringC& str);
-
- CFX_ByteStringC GetWord();
-
- // Find the token and its |nParams| parameters from the start of data,
- // and move the current position to the start of those parameters.
- bool FindTagParamFromStart(const CFX_ByteStringC& token, int nParams);
-
- // For testing only.
- uint32_t GetCurPos() const { return m_dwCurPos; }
-
- private:
- void ParseWord(const uint8_t*& pStart, uint32_t& dwSize);
-
- const uint8_t* m_pData;
- uint32_t m_dwSize;
- uint32_t m_dwCurPos;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_SIMPLE_PARSER_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_simple_parser_unittest.cpp b/core/fpdfapi/fpdf_parser/cpdf_simple_parser_unittest.cpp
deleted file mode 100644
index 50bbb528c5..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_simple_parser_unittest.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h"
-
-#include <string>
-
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h"
-#include "core/fxcrt/fx_basic.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/test_support.h"
-
-TEST(SimpleParserTest, GetWord) {
- pdfium::StrFuncTestData test_data[] = {
- // Empty src string.
- STR_IN_OUT_CASE("", ""),
- // Content with whitespaces only.
- STR_IN_OUT_CASE(" \t \0 \n", ""),
- // Content with comments only.
- STR_IN_OUT_CASE("%this is a test case\r\n%2nd line", ""),
- // Mixed whitespaces and comments.
- STR_IN_OUT_CASE(" \t \0%try()%haha\n %another line \aa", ""),
- // Name.
- STR_IN_OUT_CASE(" /Tester ", "/Tester"),
- // String.
- STR_IN_OUT_CASE("\t(nice day)!\n ", "(nice day)"),
- // String with nested braces.
- STR_IN_OUT_CASE("\t(It is a (long) day)!\n ", "(It is a (long) day)"),
- // String with escaped chars.
- STR_IN_OUT_CASE("\t(It is a \\(long\\) day!)hi\n ",
- "(It is a \\(long\\) day!)"),
- // Hex string.
- STR_IN_OUT_CASE(" \n<4545acdfedertt>abc ", "<4545acdfedertt>"),
- STR_IN_OUT_CASE(" \n<4545a<ed>ertt>abc ", "<4545a<ed>"),
- // Dictionary.
- STR_IN_OUT_CASE("<</oc 234 /color 2 3 R>>", "<<"),
- STR_IN_OUT_CASE("\t\t<< /abc>>", "<<"),
- // Handling ending delimiters.
- STR_IN_OUT_CASE("> little bear", ">"),
- STR_IN_OUT_CASE(") another bear", ")"), STR_IN_OUT_CASE(">> end ", ">>"),
- // No ending delimiters.
- STR_IN_OUT_CASE("(sdfgfgbcv", "(sdfgfgbcv"),
- // Regular cases.
- STR_IN_OUT_CASE("apple pear", "apple"),
- STR_IN_OUT_CASE(" pi=3.1415 ", "pi=3.1415"),
- STR_IN_OUT_CASE(" p t x c ", "p"), STR_IN_OUT_CASE(" pt\0xc ", "pt"),
- STR_IN_OUT_CASE(" $^&&*\t\0sdff ", "$^&&*"),
- STR_IN_OUT_CASE("\n\r+3.5656 -11.0", "+3.5656"),
- };
- for (size_t i = 0; i < FX_ArraySize(test_data); ++i) {
- const pdfium::StrFuncTestData& data = test_data[i];
- CPDF_SimpleParser parser(data.input, data.input_size);
- CFX_ByteStringC word = parser.GetWord();
- EXPECT_EQ(std::string(reinterpret_cast<const char*>(data.expected),
- data.expected_size),
- std::string(word.c_str(), word.GetLength()))
- << " for case " << i;
- }
-}
-
-TEST(SimpleParserTest, FindTagParamFromStart) {
- struct FindTagTestStruct {
- const unsigned char* input;
- unsigned int input_size;
- const char* token;
- int num_params;
- bool result;
- unsigned int result_pos;
- } test_data[] = {
- // Empty strings.
- STR_IN_TEST_CASE("", "Tj", 1, false, 0),
- STR_IN_TEST_CASE("", "", 1, false, 0),
- // Empty token.
- STR_IN_TEST_CASE(" T j", "", 1, false, 5),
- // No parameter.
- STR_IN_TEST_CASE("Tj", "Tj", 1, false, 2),
- STR_IN_TEST_CASE("(Tj", "Tj", 1, false, 3),
- // Partial token match.
- STR_IN_TEST_CASE("\r12\t34 56 78Tj", "Tj", 1, false, 15),
- // Regular cases with various parameters.
- STR_IN_TEST_CASE("\r\0abd Tj", "Tj", 1, true, 0),
- STR_IN_TEST_CASE("12 4 Tj 3 46 Tj", "Tj", 1, true, 2),
- STR_IN_TEST_CASE("er^ 2 (34) (5667) Tj", "Tj", 2, true, 5),
- STR_IN_TEST_CASE("<344> (232)\t343.4\n12 45 Tj", "Tj", 3, true, 11),
- STR_IN_TEST_CASE("1 2 3 4 5 6 7 8 cm", "cm", 6, true, 3),
- };
- for (size_t i = 0; i < FX_ArraySize(test_data); ++i) {
- const FindTagTestStruct& data = test_data[i];
- CPDF_SimpleParser parser(data.input, data.input_size);
- EXPECT_EQ(data.result,
- parser.FindTagParamFromStart(data.token, data.num_params))
- << " for case " << i;
- EXPECT_EQ(data.result_pos, parser.GetCurPos()) << " for case " << i;
- }
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_stream.cpp b/core/fpdfapi/fpdf_parser/cpdf_stream.cpp
deleted file mode 100644
index 4f6d046397..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_stream.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
-
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h"
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h"
-#include "third_party/base/numerics/safe_conversions.h"
-#include "third_party/base/stl_util.h"
-
-CPDF_Stream::CPDF_Stream() {}
-
-CPDF_Stream::CPDF_Stream(uint8_t* pData, uint32_t size, CPDF_Dictionary* pDict)
- : m_pDict(pDict),
- m_dwSize(size),
- m_pDataBuf(pData) {}
-
-CPDF_Stream::~CPDF_Stream() {}
-
-CPDF_Object::Type CPDF_Stream::GetType() const {
- return STREAM;
-}
-
-CPDF_Dictionary* CPDF_Stream::GetDict() const {
- return m_pDict.get();
-}
-
-bool CPDF_Stream::IsStream() const {
- return true;
-}
-
-CPDF_Stream* CPDF_Stream::AsStream() {
- return this;
-}
-
-const CPDF_Stream* CPDF_Stream::AsStream() const {
- return this;
-}
-
-void CPDF_Stream::InitStream(const uint8_t* pData,
- uint32_t size,
- CPDF_Dictionary* pDict) {
- m_pDict.reset(pDict);
- m_bMemoryBased = true;
- m_pFile = nullptr;
- m_pDataBuf.reset(FX_Alloc(uint8_t, size));
- if (pData)
- FXSYS_memcpy(m_pDataBuf.get(), pData, size);
- m_dwSize = size;
- if (m_pDict)
- m_pDict->SetIntegerFor("Length", m_dwSize);
-}
-
-void CPDF_Stream::InitStreamFromFile(IFX_FileRead* pFile,
- CPDF_Dictionary* pDict) {
- m_pDict.reset(pDict);
- m_bMemoryBased = false;
- m_pDataBuf.reset();
- m_pFile = pFile;
- m_dwSize = pdfium::base::checked_cast<uint32_t>(pFile->GetSize());
- if (m_pDict)
- m_pDict->SetIntegerFor("Length", m_dwSize);
-}
-
-CPDF_Object* CPDF_Stream::Clone() const {
- return CloneObjectNonCyclic(false);
-}
-
-CPDF_Object* CPDF_Stream::CloneNonCyclic(
- bool bDirect,
- std::set<const CPDF_Object*>* pVisited) const {
- pVisited->insert(this);
- CPDF_StreamAcc acc;
- acc.LoadAllData(this, TRUE);
- uint32_t streamSize = acc.GetSize();
- CPDF_Dictionary* pDict = GetDict();
- if (pDict && !pdfium::ContainsKey(*pVisited, pDict)) {
- pDict = ToDictionary(
- static_cast<CPDF_Object*>(pDict)->CloneNonCyclic(bDirect, pVisited));
- }
-
- return new CPDF_Stream(acc.DetachData(), streamSize, pDict);
-}
-
-void CPDF_Stream::SetData(const uint8_t* pData, uint32_t size) {
- m_bMemoryBased = true;
- m_pDataBuf.reset(FX_Alloc(uint8_t, size));
- if (pData)
- FXSYS_memcpy(m_pDataBuf.get(), pData, size);
- m_dwSize = size;
- if (!m_pDict)
- m_pDict.reset(new CPDF_Dictionary());
- m_pDict->SetIntegerFor("Length", size);
- m_pDict->RemoveFor("Filter");
- m_pDict->RemoveFor("DecodeParms");
-}
-
-FX_BOOL CPDF_Stream::ReadRawData(FX_FILESIZE offset,
- uint8_t* buf,
- uint32_t size) const {
- if (m_bMemoryBased && m_pFile)
- return m_pFile->ReadBlock(buf, offset, size);
-
- if (m_pDataBuf)
- FXSYS_memcpy(buf, m_pDataBuf.get() + offset, size);
-
- return TRUE;
-}
-
-CFX_WideString CPDF_Stream::GetUnicodeText() const {
- CPDF_StreamAcc stream;
- stream.LoadAllData(this, FALSE);
- return PDF_DecodeText(stream.GetData(), stream.GetSize());
-}
-
diff --git a/core/fpdfapi/fpdf_parser/cpdf_stream.h b/core/fpdfapi/fpdf_parser/cpdf_stream.h
deleted file mode 100644
index e3bba96346..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_stream.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_STREAM_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_STREAM_H_
-
-#include <memory>
-#include <set>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-#include "core/fxcrt/fx_basic.h"
-
-class CPDF_Stream : public CPDF_Object {
- public:
- CPDF_Stream();
-
- // Takes ownership of |pData| and |pDict|.
- CPDF_Stream(uint8_t* pData, uint32_t size, CPDF_Dictionary* pDict);
-
- // CPDF_Object.
- Type GetType() const override;
- CPDF_Object* Clone() const override;
- CPDF_Dictionary* GetDict() const override;
- CFX_WideString GetUnicodeText() const override;
- bool IsStream() const override;
- CPDF_Stream* AsStream() override;
- const CPDF_Stream* AsStream() const override;
-
- uint32_t GetRawSize() const { return m_dwSize; }
- uint8_t* GetRawData() const { return m_pDataBuf.get(); }
-
- // Does not takes onwership of |pData|, copies into internally-owned buffer.
- void SetData(const uint8_t* pData, uint32_t size);
-
- void InitStream(const uint8_t* pData, uint32_t size, CPDF_Dictionary* pDict);
- void InitStreamFromFile(IFX_FileRead* pFile, CPDF_Dictionary* pDict);
-
- FX_BOOL ReadRawData(FX_FILESIZE start_pos,
- uint8_t* pBuf,
- uint32_t buf_size) const;
-
- bool IsMemoryBased() const { return m_bMemoryBased; }
-
- protected:
- ~CPDF_Stream() override;
- CPDF_Object* CloneNonCyclic(
- bool bDirect,
- std::set<const CPDF_Object*>* pVisited) const override;
-
- std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> m_pDict;
- bool m_bMemoryBased = true;
- uint32_t m_dwSize = 0;
- std::unique_ptr<uint8_t, FxFreeDeleter> m_pDataBuf;
- IFX_FileRead* m_pFile = nullptr;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_STREAM_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_stream_acc.cpp b/core/fpdfapi/fpdf_parser/cpdf_stream_acc.cpp
deleted file mode 100644
index a19b796151..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_stream_acc.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h"
-
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h"
-
-CPDF_StreamAcc::CPDF_StreamAcc()
- : m_pData(nullptr),
- m_dwSize(0),
- m_bNewBuf(FALSE),
- m_pImageParam(nullptr),
- m_pStream(nullptr),
- m_pSrcData(nullptr) {}
-
-void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream,
- FX_BOOL bRawAccess,
- uint32_t estimated_size,
- FX_BOOL bImageAcc) {
- if (!pStream)
- return;
-
- m_pStream = pStream;
- if (pStream->IsMemoryBased() &&
- (!pStream->GetDict()->KeyExist("Filter") || bRawAccess)) {
- m_dwSize = pStream->GetRawSize();
- m_pData = pStream->GetRawData();
- return;
- }
- uint8_t* pSrcData;
- uint32_t dwSrcSize = pStream->GetRawSize();
- if (dwSrcSize == 0)
- return;
-
- if (!pStream->IsMemoryBased()) {
- pSrcData = m_pSrcData = FX_Alloc(uint8_t, dwSrcSize);
- if (!pStream->ReadRawData(0, pSrcData, dwSrcSize))
- return;
- } else {
- pSrcData = pStream->GetRawData();
- }
- if (!pStream->GetDict()->KeyExist("Filter") || bRawAccess) {
- m_pData = pSrcData;
- m_dwSize = dwSrcSize;
- } else {
- FX_BOOL bRet = PDF_DataDecode(pSrcData, dwSrcSize, m_pStream->GetDict(),
- m_pData, m_dwSize, m_ImageDecoder,
- m_pImageParam, estimated_size, bImageAcc);
- if (!bRet) {
- m_pData = pSrcData;
- m_dwSize = dwSrcSize;
- }
- }
- if (pSrcData != pStream->GetRawData() && pSrcData != m_pData)
- FX_Free(pSrcData);
- m_pSrcData = nullptr;
- m_bNewBuf = m_pData != pStream->GetRawData();
-}
-
-CPDF_StreamAcc::~CPDF_StreamAcc() {
- if (m_bNewBuf)
- FX_Free(m_pData);
- FX_Free(m_pSrcData);
-}
-
-const uint8_t* CPDF_StreamAcc::GetData() const {
- if (m_bNewBuf)
- return m_pData;
- return m_pStream ? m_pStream->GetRawData() : nullptr;
-}
-
-uint32_t CPDF_StreamAcc::GetSize() const {
- if (m_bNewBuf)
- return m_dwSize;
- return m_pStream ? m_pStream->GetRawSize() : 0;
-}
-
-uint8_t* CPDF_StreamAcc::DetachData() {
- if (m_bNewBuf) {
- uint8_t* p = m_pData;
- m_pData = nullptr;
- m_dwSize = 0;
- return p;
- }
- uint8_t* p = FX_Alloc(uint8_t, m_dwSize);
- FXSYS_memcpy(p, m_pData, m_dwSize);
- return p;
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_stream_acc.h b/core/fpdfapi/fpdf_parser/cpdf_stream_acc.h
deleted file mode 100644
index cf2bc8a01d..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_stream_acc.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_STREAM_ACC_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_STREAM_ACC_H_
-
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-
-class CPDF_StreamAcc {
- public:
- CPDF_StreamAcc();
- ~CPDF_StreamAcc();
-
- void LoadAllData(const CPDF_Stream* pStream,
- FX_BOOL bRawAccess = FALSE,
- uint32_t estimated_size = 0,
- FX_BOOL bImageAcc = FALSE);
-
- const CPDF_Stream* GetStream() const { return m_pStream; }
- CPDF_Dictionary* GetDict() const {
- return m_pStream ? m_pStream->GetDict() : nullptr;
- }
-
- const uint8_t* GetData() const;
- uint32_t GetSize() const;
- const CFX_ByteString& GetImageDecoder() const { return m_ImageDecoder; }
- const CPDF_Dictionary* GetImageParam() const { return m_pImageParam; }
- uint8_t* DetachData();
-
- protected:
- uint8_t* m_pData;
- uint32_t m_dwSize;
- FX_BOOL m_bNewBuf;
- CFX_ByteString m_ImageDecoder;
- CPDF_Dictionary* m_pImageParam;
- const CPDF_Stream* m_pStream;
- uint8_t* m_pSrcData;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_STREAM_ACC_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_string.cpp b/core/fpdfapi/fpdf_parser/cpdf_string.cpp
deleted file mode 100644
index 4b42b8c22b..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_string.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_string.h"
-
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h"
-
-CPDF_String::CPDF_String() : m_bHex(FALSE) {}
-
-CPDF_String::CPDF_String(const CFX_ByteString& str, FX_BOOL bHex)
- : m_String(str), m_bHex(bHex) {}
-
-CPDF_String::CPDF_String(const CFX_WideString& str) : m_bHex(FALSE) {
- m_String = PDF_EncodeText(str);
-}
-
-CPDF_String::~CPDF_String() {}
-
-CPDF_Object::Type CPDF_String::GetType() const {
- return STRING;
-}
-
-CPDF_Object* CPDF_String::Clone() const {
- return new CPDF_String(m_String, m_bHex);
-}
-
-CFX_ByteString CPDF_String::GetString() const {
- return m_String;
-}
-
-void CPDF_String::SetString(const CFX_ByteString& str) {
- m_String = str;
-}
-
-bool CPDF_String::IsString() const {
- return true;
-}
-
-CPDF_String* CPDF_String::AsString() {
- return this;
-}
-
-const CPDF_String* CPDF_String::AsString() const {
- return this;
-}
-
-CFX_WideString CPDF_String::GetUnicodeText() const {
- return PDF_DecodeText(m_String);
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_string.h b/core/fpdfapi/fpdf_parser/cpdf_string.h
deleted file mode 100644
index 2ce0d02ed7..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_string.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_STRING_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_STRING_H_
-
-#include "core/fpdfapi/fpdf_parser/cpdf_object.h"
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-
-class CPDF_String : public CPDF_Object {
- public:
- CPDF_String();
- CPDF_String(const CFX_ByteString& str, FX_BOOL bHex);
- explicit CPDF_String(const CFX_WideString& str);
-
- // CPDF_Object.
- Type GetType() const override;
- CPDF_Object* Clone() const override;
- CFX_ByteString GetString() const override;
- CFX_WideString GetUnicodeText() const override;
- void SetString(const CFX_ByteString& str) override;
- bool IsString() const override;
- CPDF_String* AsString() override;
- const CPDF_String* AsString() const override;
-
- FX_BOOL IsHex() const { return m_bHex; }
-
- protected:
- ~CPDF_String() override;
-
- CFX_ByteString m_String;
- FX_BOOL m_bHex;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_STRING_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp b/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp
deleted file mode 100644
index 32a75f98da..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp
+++ /dev/null
@@ -1,997 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h"
-
-#include <vector>
-
-#include "core/fpdfapi/cpdf_modulemgr.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_boolean.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_crypto_handler.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_name.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_null.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_number.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_string.h"
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h"
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h"
-#include "core/fxcrt/fx_ext.h"
-#include "third_party/base/numerics/safe_math.h"
-
-namespace {
-
-struct SearchTagRecord {
- CFX_ByteStringC m_bsTag;
- FX_STRSIZE m_Offset;
-};
-
-} // namespace
-
-// static
-int CPDF_SyntaxParser::s_CurrentRecursionDepth = 0;
-
-CPDF_SyntaxParser::CPDF_SyntaxParser()
- : CPDF_SyntaxParser(CFX_WeakPtr<CFX_ByteStringPool>()) {}
-
-CPDF_SyntaxParser::CPDF_SyntaxParser(
- const CFX_WeakPtr<CFX_ByteStringPool>& pPool)
- : m_MetadataObjnum(0),
- m_pFileAccess(nullptr),
- m_pFileBuf(nullptr),
- m_BufSize(CPDF_ModuleMgr::kFileBufSize),
- m_pPool(pPool) {}
-
-CPDF_SyntaxParser::~CPDF_SyntaxParser() {
- FX_Free(m_pFileBuf);
-}
-
-FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, uint8_t& ch) {
- CFX_AutoRestorer<FX_FILESIZE> save_pos(&m_Pos);
- m_Pos = pos;
- return GetNextChar(ch);
-}
-
-FX_BOOL CPDF_SyntaxParser::GetNextChar(uint8_t& ch) {
- FX_FILESIZE pos = m_Pos + m_HeaderOffset;
- if (pos >= m_FileLen)
- return FALSE;
-
- if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) {
- FX_FILESIZE read_pos = pos;
- uint32_t read_size = m_BufSize;
- if ((FX_FILESIZE)read_size > m_FileLen)
- read_size = (uint32_t)m_FileLen;
-
- if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) {
- if (m_FileLen < (FX_FILESIZE)read_size) {
- read_pos = 0;
- read_size = (uint32_t)m_FileLen;
- } else {
- read_pos = m_FileLen - read_size;
- }
- }
-
- if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size))
- return FALSE;
-
- m_BufOffset = read_pos;
- }
- ch = m_pFileBuf[pos - m_BufOffset];
- m_Pos++;
- return TRUE;
-}
-
-FX_BOOL CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch) {
- pos += m_HeaderOffset;
- if (pos >= m_FileLen)
- return FALSE;
-
- if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) {
- FX_FILESIZE read_pos;
- if (pos < (FX_FILESIZE)m_BufSize)
- read_pos = 0;
- else
- read_pos = pos - m_BufSize + 1;
-
- uint32_t read_size = m_BufSize;
- if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) {
- if (m_FileLen < (FX_FILESIZE)read_size) {
- read_pos = 0;
- read_size = (uint32_t)m_FileLen;
- } else {
- read_pos = m_FileLen - read_size;
- }
- }
-
- if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size))
- return FALSE;
-
- m_BufOffset = read_pos;
- }
- ch = m_pFileBuf[pos - m_BufOffset];
- return TRUE;
-}
-
-FX_BOOL CPDF_SyntaxParser::ReadBlock(uint8_t* pBuf, uint32_t size) {
- if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size))
- return FALSE;
- m_Pos += size;
- return TRUE;
-}
-
-void CPDF_SyntaxParser::GetNextWordInternal(bool* bIsNumber) {
- m_WordSize = 0;
- if (bIsNumber)
- *bIsNumber = true;
-
- uint8_t ch;
- if (!GetNextChar(ch))
- return;
-
- while (1) {
- while (PDFCharIsWhitespace(ch)) {
- if (!GetNextChar(ch))
- return;
- }
-
- if (ch != '%')
- break;
-
- while (1) {
- if (!GetNextChar(ch))
- return;
- if (PDFCharIsLineEnding(ch))
- break;
- }
- }
-
- if (PDFCharIsDelimiter(ch)) {
- if (bIsNumber)
- *bIsNumber = false;
-
- m_WordBuffer[m_WordSize++] = ch;
- if (ch == '/') {
- while (1) {
- if (!GetNextChar(ch))
- return;
-
- if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) {
- m_Pos--;
- return;
- }
-
- if (m_WordSize < sizeof(m_WordBuffer) - 1)
- m_WordBuffer[m_WordSize++] = ch;
- }
- } else if (ch == '<') {
- if (!GetNextChar(ch))
- return;
-
- if (ch == '<')
- m_WordBuffer[m_WordSize++] = ch;
- else
- m_Pos--;
- } else if (ch == '>') {
- if (!GetNextChar(ch))
- return;
-
- if (ch == '>')
- m_WordBuffer[m_WordSize++] = ch;
- else
- m_Pos--;
- }
- return;
- }
-
- while (1) {
- if (m_WordSize < sizeof(m_WordBuffer) - 1)
- m_WordBuffer[m_WordSize++] = ch;
-
- if (!PDFCharIsNumeric(ch)) {
- if (bIsNumber)
- *bIsNumber = false;
- }
-
- if (!GetNextChar(ch))
- return;
-
- if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) {
- m_Pos--;
- break;
- }
- }
-}
-
-CFX_ByteString CPDF_SyntaxParser::ReadString() {
- uint8_t ch;
- if (!GetNextChar(ch))
- return CFX_ByteString();
-
- CFX_ByteTextBuf buf;
- int32_t parlevel = 0;
- int32_t status = 0;
- int32_t iEscCode = 0;
- while (1) {
- switch (status) {
- case 0:
- if (ch == ')') {
- if (parlevel == 0) {
- return buf.MakeString();
- }
- parlevel--;
- buf.AppendChar(')');
- } else if (ch == '(') {
- parlevel++;
- buf.AppendChar('(');
- } else if (ch == '\\') {
- status = 1;
- } else {
- buf.AppendChar(ch);
- }
- break;
- case 1:
- if (ch >= '0' && ch <= '7') {
- iEscCode = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch));
- status = 2;
- break;
- }
-
- if (ch == 'n') {
- buf.AppendChar('\n');
- } else if (ch == 'r') {
- buf.AppendChar('\r');
- } else if (ch == 't') {
- buf.AppendChar('\t');
- } else if (ch == 'b') {
- buf.AppendChar('\b');
- } else if (ch == 'f') {
- buf.AppendChar('\f');
- } else if (ch == '\r') {
- status = 4;
- break;
- } else if (ch != '\n') {
- buf.AppendChar(ch);
- }
- status = 0;
- break;
- case 2:
- if (ch >= '0' && ch <= '7') {
- iEscCode =
- iEscCode * 8 + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch));
- status = 3;
- } else {
- buf.AppendChar(iEscCode);
- status = 0;
- continue;
- }
- break;
- case 3:
- if (ch >= '0' && ch <= '7') {
- iEscCode =
- iEscCode * 8 + FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch));
- buf.AppendChar(iEscCode);
- status = 0;
- } else {
- buf.AppendChar(iEscCode);
- status = 0;
- continue;
- }
- break;
- case 4:
- status = 0;
- if (ch != '\n')
- continue;
- break;
- }
-
- if (!GetNextChar(ch))
- break;
- }
-
- GetNextChar(ch);
- return buf.MakeString();
-}
-
-CFX_ByteString CPDF_SyntaxParser::ReadHexString() {
- uint8_t ch;
- if (!GetNextChar(ch))
- return CFX_ByteString();
-
- CFX_ByteTextBuf buf;
- bool bFirst = true;
- uint8_t code = 0;
- while (1) {
- if (ch == '>')
- break;
-
- if (std::isxdigit(ch)) {
- int val = FXSYS_toHexDigit(ch);
- if (bFirst) {
- code = val * 16;
- } else {
- code += val;
- buf.AppendByte(code);
- }
- bFirst = !bFirst;
- }
-
- if (!GetNextChar(ch))
- break;
- }
- if (!bFirst)
- buf.AppendByte(code);
-
- return buf.MakeString();
-}
-
-void CPDF_SyntaxParser::ToNextLine() {
- uint8_t ch;
- while (GetNextChar(ch)) {
- if (ch == '\n')
- break;
-
- if (ch == '\r') {
- GetNextChar(ch);
- if (ch != '\n')
- --m_Pos;
- break;
- }
- }
-}
-
-void CPDF_SyntaxParser::ToNextWord() {
- uint8_t ch;
- if (!GetNextChar(ch))
- return;
-
- while (1) {
- while (PDFCharIsWhitespace(ch)) {
- if (!GetNextChar(ch))
- return;
- }
-
- if (ch != '%')
- break;
-
- while (1) {
- if (!GetNextChar(ch))
- return;
- if (PDFCharIsLineEnding(ch))
- break;
- }
- }
- m_Pos--;
-}
-
-CFX_ByteString CPDF_SyntaxParser::GetNextWord(bool* bIsNumber) {
- GetNextWordInternal(bIsNumber);
- return CFX_ByteString((const FX_CHAR*)m_WordBuffer, m_WordSize);
-}
-
-CFX_ByteString CPDF_SyntaxParser::GetKeyword() {
- return GetNextWord(nullptr);
-}
-
-CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum,
- uint32_t gennum,
- FX_BOOL bDecrypt) {
- CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth);
- if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth)
- return nullptr;
-
- FX_FILESIZE SavedObjPos = m_Pos;
- bool bIsNumber;
- CFX_ByteString word = GetNextWord(&bIsNumber);
- if (word.GetLength() == 0)
- return nullptr;
-
- if (bIsNumber) {
- FX_FILESIZE SavedPos = m_Pos;
- CFX_ByteString nextword = GetNextWord(&bIsNumber);
- if (bIsNumber) {
- CFX_ByteString nextword2 = GetNextWord(nullptr);
- if (nextword2 == "R")
- return new CPDF_Reference(pObjList, FXSYS_atoui(word.c_str()));
- }
- m_Pos = SavedPos;
- return new CPDF_Number(word.AsStringC());
- }
-
- if (word == "true" || word == "false")
- return new CPDF_Boolean(word == "true");
-
- if (word == "null")
- return new CPDF_Null;
-
- if (word == "(") {
- CFX_ByteString str = ReadString();
- if (m_pCryptoHandler && bDecrypt)
- m_pCryptoHandler->Decrypt(objnum, gennum, str);
- return new CPDF_String(MaybeIntern(str), FALSE);
- }
-
- if (word == "<") {
- CFX_ByteString str = ReadHexString();
- if (m_pCryptoHandler && bDecrypt)
- m_pCryptoHandler->Decrypt(objnum, gennum, str);
- return new CPDF_String(MaybeIntern(str), TRUE);
- }
-
- if (word == "[") {
- CPDF_Array* pArray = new CPDF_Array;
- while (CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, true))
- pArray->Add(pObj);
-
- return pArray;
- }
-
- if (word[0] == '/') {
- return new CPDF_Name(MaybeIntern(
- PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))));
- }
-
- if (word == "<<") {
- int32_t nKeys = 0;
- FX_FILESIZE dwSignValuePos = 0;
-
- std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict(
- new CPDF_Dictionary(m_pPool));
- while (1) {
- CFX_ByteString key = GetNextWord(nullptr);
- if (key.IsEmpty())
- return nullptr;
-
- FX_FILESIZE SavedPos = m_Pos - key.GetLength();
- if (key == ">>")
- break;
-
- if (key == "endobj") {
- m_Pos = SavedPos;
- break;
- }
-
- if (key[0] != '/')
- continue;
-
- ++nKeys;
- key = PDF_NameDecode(key);
- if (key.IsEmpty())
- continue;
-
- if (key == "/Contents")
- dwSignValuePos = m_Pos;
-
- CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, true);
- if (!pObj)
- continue;
-
- CFX_ByteString keyNoSlash(key.raw_str() + 1, key.GetLength() - 1);
- pDict->SetFor(keyNoSlash, pObj);
- }
-
- // Only when this is a signature dictionary and has contents, we reset the
- // contents to the un-decrypted form.
- if (pDict->IsSignatureDict() && dwSignValuePos) {
- CFX_AutoRestorer<FX_FILESIZE> save_pos(&m_Pos);
- m_Pos = dwSignValuePos;
- pDict->SetFor("Contents", GetObject(pObjList, objnum, gennum, false));
- }
-
- FX_FILESIZE SavedPos = m_Pos;
- CFX_ByteString nextword = GetNextWord(nullptr);
- if (nextword != "stream") {
- m_Pos = SavedPos;
- return pDict.release();
- }
- return ReadStream(pDict.release(), objnum, gennum);
- }
-
- if (word == ">>")
- m_Pos = SavedObjPos;
-
- return nullptr;
-}
-
-CPDF_Object* CPDF_SyntaxParser::GetObjectForStrict(
- CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum,
- uint32_t gennum) {
- CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth);
- if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth)
- return nullptr;
-
- FX_FILESIZE SavedObjPos = m_Pos;
- bool bIsNumber;
- CFX_ByteString word = GetNextWord(&bIsNumber);
- if (word.GetLength() == 0)
- return nullptr;
-
- if (bIsNumber) {
- FX_FILESIZE SavedPos = m_Pos;
- CFX_ByteString nextword = GetNextWord(&bIsNumber);
- if (bIsNumber) {
- CFX_ByteString nextword2 = GetNextWord(nullptr);
- if (nextword2 == "R")
- return new CPDF_Reference(pObjList, FXSYS_atoui(word.c_str()));
- }
- m_Pos = SavedPos;
- return new CPDF_Number(word.AsStringC());
- }
-
- if (word == "true" || word == "false")
- return new CPDF_Boolean(word == "true");
-
- if (word == "null")
- return new CPDF_Null;
-
- if (word == "(") {
- CFX_ByteString str = ReadString();
- if (m_pCryptoHandler)
- m_pCryptoHandler->Decrypt(objnum, gennum, str);
- return new CPDF_String(MaybeIntern(str), FALSE);
- }
-
- if (word == "<") {
- CFX_ByteString str = ReadHexString();
- if (m_pCryptoHandler)
- m_pCryptoHandler->Decrypt(objnum, gennum, str);
- return new CPDF_String(MaybeIntern(str), TRUE);
- }
-
- if (word == "[") {
- std::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Array>> pArray(
- new CPDF_Array);
- while (CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, true))
- pArray->Add(pObj);
-
- return m_WordBuffer[0] == ']' ? pArray.release() : nullptr;
- }
-
- if (word[0] == '/') {
- return new CPDF_Name(MaybeIntern(
- PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))));
- }
-
- if (word == "<<") {
- std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> pDict(
- new CPDF_Dictionary(m_pPool));
- while (1) {
- FX_FILESIZE SavedPos = m_Pos;
- CFX_ByteString key = GetNextWord(nullptr);
- if (key.IsEmpty())
- return nullptr;
-
- if (key == ">>")
- break;
-
- if (key == "endobj") {
- m_Pos = SavedPos;
- break;
- }
-
- if (key[0] != '/')
- continue;
-
- key = PDF_NameDecode(key);
- std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> obj(
- GetObject(pObjList, objnum, gennum, true));
- if (!obj) {
- uint8_t ch;
- while (GetNextChar(ch) && ch != 0x0A && ch != 0x0D) {
- continue;
- }
- return nullptr;
- }
-
- if (key.GetLength() > 1) {
- pDict->SetFor(CFX_ByteString(key.c_str() + 1, key.GetLength() - 1),
- obj.release());
- }
- }
-
- FX_FILESIZE SavedPos = m_Pos;
- CFX_ByteString nextword = GetNextWord(nullptr);
- if (nextword != "stream") {
- m_Pos = SavedPos;
- return pDict.release();
- }
-
- return ReadStream(pDict.release(), objnum, gennum);
- }
-
- if (word == ">>")
- m_Pos = SavedObjPos;
-
- return nullptr;
-}
-
-unsigned int CPDF_SyntaxParser::ReadEOLMarkers(FX_FILESIZE pos) {
- unsigned char byte1 = 0;
- unsigned char byte2 = 0;
-
- GetCharAt(pos, byte1);
- GetCharAt(pos + 1, byte2);
-
- if (byte1 == '\r' && byte2 == '\n')
- return 2;
-
- if (byte1 == '\r' || byte1 == '\n')
- return 1;
-
- return 0;
-}
-
-CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict,
- uint32_t objnum,
- uint32_t gennum) {
- CPDF_Object* pLenObj = pDict->GetObjectFor("Length");
- FX_FILESIZE len = -1;
- CPDF_Reference* pLenObjRef = ToReference(pLenObj);
-
- bool differingObjNum = !pLenObjRef || (pLenObjRef->GetObjList() &&
- pLenObjRef->GetRefObjNum() != objnum);
- if (pLenObj && differingObjNum)
- len = pLenObj->GetInteger();
-
- // Locate the start of stream.
- ToNextLine();
- FX_FILESIZE streamStartPos = m_Pos;
-
- const CFX_ByteStringC kEndStreamStr("endstream");
- const CFX_ByteStringC kEndObjStr("endobj");
-
- CPDF_CryptoHandler* pCryptoHandler =
- objnum == (uint32_t)m_MetadataObjnum ? nullptr : m_pCryptoHandler.get();
- if (!pCryptoHandler) {
- FX_BOOL bSearchForKeyword = TRUE;
- if (len >= 0) {
- pdfium::base::CheckedNumeric<FX_FILESIZE> pos = m_Pos;
- pos += len;
- if (pos.IsValid() && pos.ValueOrDie() < m_FileLen)
- m_Pos = pos.ValueOrDie();
-
- m_Pos += ReadEOLMarkers(m_Pos);
- FXSYS_memset(m_WordBuffer, 0, kEndStreamStr.GetLength() + 1);
- GetNextWordInternal(nullptr);
- // Earlier version of PDF specification doesn't require EOL marker before
- // 'endstream' keyword. If keyword 'endstream' follows the bytes in
- // specified length, it signals the end of stream.
- if (FXSYS_memcmp(m_WordBuffer, kEndStreamStr.raw_str(),
- kEndStreamStr.GetLength()) == 0) {
- bSearchForKeyword = FALSE;
- }
- }
-
- if (bSearchForKeyword) {
- // If len is not available, len needs to be calculated
- // by searching the keywords "endstream" or "endobj".
- m_Pos = streamStartPos;
- FX_FILESIZE endStreamOffset = 0;
- while (endStreamOffset >= 0) {
- endStreamOffset = FindTag(kEndStreamStr, 0);
-
- // Can't find "endstream".
- if (endStreamOffset < 0)
- break;
-
- // Stop searching when "endstream" is found.
- if (IsWholeWord(m_Pos - kEndStreamStr.GetLength(), m_FileLen,
- kEndStreamStr, TRUE)) {
- endStreamOffset = m_Pos - streamStartPos - kEndStreamStr.GetLength();
- break;
- }
- }
-
- m_Pos = streamStartPos;
- FX_FILESIZE endObjOffset = 0;
- while (endObjOffset >= 0) {
- endObjOffset = FindTag(kEndObjStr, 0);
-
- // Can't find "endobj".
- if (endObjOffset < 0)
- break;
-
- // Stop searching when "endobj" is found.
- if (IsWholeWord(m_Pos - kEndObjStr.GetLength(), m_FileLen, kEndObjStr,
- TRUE)) {
- endObjOffset = m_Pos - streamStartPos - kEndObjStr.GetLength();
- break;
- }
- }
-
- // Can't find "endstream" or "endobj".
- if (endStreamOffset < 0 && endObjOffset < 0) {
- pDict->Release();
- return nullptr;
- }
-
- if (endStreamOffset < 0 && endObjOffset >= 0) {
- // Correct the position of end stream.
- endStreamOffset = endObjOffset;
- } else if (endStreamOffset >= 0 && endObjOffset < 0) {
- // Correct the position of end obj.
- endObjOffset = endStreamOffset;
- } else if (endStreamOffset > endObjOffset) {
- endStreamOffset = endObjOffset;
- }
-
- len = endStreamOffset;
- int numMarkers = ReadEOLMarkers(streamStartPos + endStreamOffset - 2);
- if (numMarkers == 2) {
- len -= 2;
- } else {
- numMarkers = ReadEOLMarkers(streamStartPos + endStreamOffset - 1);
- if (numMarkers == 1) {
- len -= 1;
- }
- }
-
- if (len < 0) {
- pDict->Release();
- return nullptr;
- }
- pDict->SetIntegerFor("Length", len);
- }
- m_Pos = streamStartPos;
- }
-
- if (len < 0) {
- pDict->Release();
- return nullptr;
- }
-
- uint8_t* pData = nullptr;
- if (len > 0) {
- pData = FX_Alloc(uint8_t, len);
- ReadBlock(pData, len);
- if (pCryptoHandler) {
- CFX_BinaryBuf dest_buf;
- dest_buf.EstimateSize(pCryptoHandler->DecryptGetSize(len));
-
- void* context = pCryptoHandler->DecryptStart(objnum, gennum);
- pCryptoHandler->DecryptStream(context, pData, len, dest_buf);
- pCryptoHandler->DecryptFinish(context, dest_buf);
-
- FX_Free(pData);
- pData = dest_buf.GetBuffer();
- len = dest_buf.GetSize();
- dest_buf.DetachBuffer();
- }
- }
-
- CPDF_Stream* pStream = new CPDF_Stream(pData, len, pDict);
- streamStartPos = m_Pos;
- FXSYS_memset(m_WordBuffer, 0, kEndObjStr.GetLength() + 1);
-
- GetNextWordInternal(nullptr);
-
- int numMarkers = ReadEOLMarkers(m_Pos);
- if (m_WordSize == static_cast<unsigned int>(kEndObjStr.GetLength()) &&
- numMarkers != 0 &&
- FXSYS_memcmp(m_WordBuffer, kEndObjStr.raw_str(),
- kEndObjStr.GetLength()) == 0) {
- m_Pos = streamStartPos;
- }
- return pStream;
-}
-
-void CPDF_SyntaxParser::InitParser(IFX_FileRead* pFileAccess,
- uint32_t HeaderOffset) {
- FX_Free(m_pFileBuf);
-
- m_pFileBuf = FX_Alloc(uint8_t, m_BufSize);
- m_HeaderOffset = HeaderOffset;
- m_FileLen = pFileAccess->GetSize();
- m_Pos = 0;
- m_pFileAccess = pFileAccess;
- m_BufOffset = 0;
- pFileAccess->ReadBlock(
- m_pFileBuf, 0,
- (size_t)((FX_FILESIZE)m_BufSize > m_FileLen ? m_FileLen : m_BufSize));
-}
-
-uint32_t CPDF_SyntaxParser::GetDirectNum() {
- bool bIsNumber;
- GetNextWordInternal(&bIsNumber);
- if (!bIsNumber)
- return 0;
-
- m_WordBuffer[m_WordSize] = 0;
- return FXSYS_atoui(reinterpret_cast<const FX_CHAR*>(m_WordBuffer));
-}
-
-bool CPDF_SyntaxParser::IsWholeWord(FX_FILESIZE startpos,
- FX_FILESIZE limit,
- const CFX_ByteStringC& tag,
- FX_BOOL checkKeyword) {
- const uint32_t taglen = tag.GetLength();
-
- bool bCheckLeft = !PDFCharIsDelimiter(tag[0]) && !PDFCharIsWhitespace(tag[0]);
- bool bCheckRight = !PDFCharIsDelimiter(tag[taglen - 1]) &&
- !PDFCharIsWhitespace(tag[taglen - 1]);
-
- uint8_t ch;
- if (bCheckRight && startpos + (int32_t)taglen <= limit &&
- GetCharAt(startpos + (int32_t)taglen, ch)) {
- if (PDFCharIsNumeric(ch) || PDFCharIsOther(ch) ||
- (checkKeyword && PDFCharIsDelimiter(ch))) {
- return false;
- }
- }
-
- if (bCheckLeft && startpos > 0 && GetCharAt(startpos - 1, ch)) {
- if (PDFCharIsNumeric(ch) || PDFCharIsOther(ch) ||
- (checkKeyword && PDFCharIsDelimiter(ch))) {
- return false;
- }
- }
- return true;
-}
-
-// TODO(dsinclair): Split into a SearchWordForward and SearchWordBackwards
-// and drop the bool.
-FX_BOOL CPDF_SyntaxParser::SearchWord(const CFX_ByteStringC& tag,
- FX_BOOL bWholeWord,
- FX_BOOL bForward,
- FX_FILESIZE limit) {
- int32_t taglen = tag.GetLength();
- if (taglen == 0)
- return FALSE;
-
- FX_FILESIZE pos = m_Pos;
- int32_t offset = 0;
- if (!bForward)
- offset = taglen - 1;
-
- const uint8_t* tag_data = tag.raw_str();
- uint8_t byte;
- while (1) {
- if (bForward) {
- if (limit && pos >= m_Pos + limit)
- return FALSE;
-
- if (!GetCharAt(pos, byte))
- return FALSE;
-
- } else {
- if (limit && pos <= m_Pos - limit)
- return FALSE;
-
- if (!GetCharAtBackward(pos, byte))
- return FALSE;
- }
-
- if (byte == tag_data[offset]) {
- if (bForward) {
- offset++;
- if (offset < taglen) {
- pos++;
- continue;
- }
- } else {
- offset--;
- if (offset >= 0) {
- pos--;
- continue;
- }
- }
-
- FX_FILESIZE startpos = bForward ? pos - taglen + 1 : pos;
- if (!bWholeWord || IsWholeWord(startpos, limit, tag, FALSE)) {
- m_Pos = startpos;
- return TRUE;
- }
- }
-
- if (bForward) {
- offset = byte == tag_data[0] ? 1 : 0;
- pos++;
- } else {
- offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1;
- pos--;
- }
-
- if (pos < 0)
- return FALSE;
- }
-
- return FALSE;
-}
-
-int32_t CPDF_SyntaxParser::SearchMultiWord(const CFX_ByteStringC& tags,
- FX_BOOL bWholeWord,
- FX_FILESIZE limit) {
- int32_t ntags = 1;
- for (int i = 0; i < tags.GetLength(); ++i) {
- if (tags[i] == 0)
- ++ntags;
- }
-
- // Ensure that the input byte string happens to be nul-terminated. This
- // need not be the case, but the loop below uses this guarantee to put
- // the last pattern into the vector.
- ASSERT(tags[tags.GetLength()] == 0);
- std::vector<SearchTagRecord> patterns(ntags);
- uint32_t start = 0;
- uint32_t itag = 0;
- uint32_t max_len = 0;
- for (int i = 0; i <= tags.GetLength(); ++i) {
- if (tags[i] == 0) {
- uint32_t len = i - start;
- max_len = std::max(len, max_len);
- patterns[itag].m_bsTag = tags.Mid(start, len);
- patterns[itag].m_Offset = 0;
- start = i + 1;
- ++itag;
- }
- }
-
- const FX_FILESIZE pos_limit = m_Pos + limit;
- for (FX_FILESIZE pos = m_Pos; !limit || pos < pos_limit; ++pos) {
- uint8_t byte;
- if (!GetCharAt(pos, byte))
- break;
-
- for (int i = 0; i < ntags; ++i) {
- SearchTagRecord& pat = patterns[i];
- if (pat.m_bsTag[pat.m_Offset] != byte) {
- pat.m_Offset = (pat.m_bsTag[0] == byte) ? 1 : 0;
- continue;
- }
-
- ++pat.m_Offset;
- if (pat.m_Offset != pat.m_bsTag.GetLength())
- continue;
-
- if (!bWholeWord || IsWholeWord(pos - pat.m_bsTag.GetLength(), limit,
- pat.m_bsTag, FALSE)) {
- return i;
- }
-
- pat.m_Offset = (pat.m_bsTag[0] == byte) ? 1 : 0;
- }
- }
- return -1;
-}
-
-FX_FILESIZE CPDF_SyntaxParser::FindTag(const CFX_ByteStringC& tag,
- FX_FILESIZE limit) {
- int32_t taglen = tag.GetLength();
- int32_t match = 0;
- limit += m_Pos;
- FX_FILESIZE startpos = m_Pos;
-
- while (1) {
- uint8_t ch;
- if (!GetNextChar(ch))
- return -1;
-
- if (ch == tag[match]) {
- match++;
- if (match == taglen)
- return m_Pos - startpos - taglen;
- } else {
- match = ch == tag[0] ? 1 : 0;
- }
-
- if (limit && m_Pos == limit)
- return -1;
- }
- return -1;
-}
-
-void CPDF_SyntaxParser::SetEncrypt(
- std::unique_ptr<CPDF_CryptoHandler> pCryptoHandler) {
- m_pCryptoHandler = std::move(pCryptoHandler);
-}
-
-CFX_ByteString CPDF_SyntaxParser::MaybeIntern(const CFX_ByteString& str) {
- return m_pPool ? m_pPool->Intern(str) : str;
-}
diff --git a/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h b/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h
deleted file mode 100644
index 3a9f1b473a..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_CPDF_SYNTAX_PARSER_H_
-#define CORE_FPDFAPI_FPDF_PARSER_CPDF_SYNTAX_PARSER_H_
-
-#include <memory>
-
-#include "core/fxcrt/cfx_string_pool_template.h"
-#include "core/fxcrt/cfx_weak_ptr.h"
-#include "core/fxcrt/fx_basic.h"
-
-class CPDF_CryptoHandler;
-class CPDF_Dictionary;
-class CPDF_IndirectObjectHolder;
-class CPDF_Object;
-class CPDF_Stream;
-class IFX_FileRead;
-
-class CPDF_SyntaxParser {
- public:
- CPDF_SyntaxParser();
- explicit CPDF_SyntaxParser(const CFX_WeakPtr<CFX_ByteStringPool>& pPool);
- ~CPDF_SyntaxParser();
-
- void InitParser(IFX_FileRead* pFileAccess, uint32_t HeaderOffset);
-
- FX_FILESIZE SavePos() const { return m_Pos; }
- void RestorePos(FX_FILESIZE pos) { m_Pos = pos; }
-
- CPDF_Object* GetObject(CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum,
- uint32_t gennum,
- FX_BOOL bDecrypt);
- CPDF_Object* GetObjectForStrict(CPDF_IndirectObjectHolder* pObjList,
- uint32_t objnum,
- uint32_t gennum);
- CFX_ByteString GetKeyword();
-
- void ToNextLine();
- void ToNextWord();
-
- FX_BOOL SearchWord(const CFX_ByteStringC& word,
- FX_BOOL bWholeWord,
- FX_BOOL bForward,
- FX_FILESIZE limit);
- int SearchMultiWord(const CFX_ByteStringC& words,
- FX_BOOL bWholeWord,
- FX_FILESIZE limit);
- FX_FILESIZE FindTag(const CFX_ByteStringC& tag, FX_FILESIZE limit);
-
- void SetEncrypt(std::unique_ptr<CPDF_CryptoHandler> pCryptoHandler);
-
- FX_BOOL ReadBlock(uint8_t* pBuf, uint32_t size);
- FX_BOOL GetCharAt(FX_FILESIZE pos, uint8_t& ch);
- CFX_ByteString GetNextWord(bool* bIsNumber);
-
- private:
- friend class CPDF_Parser;
- friend class CPDF_DataAvail;
- friend class cpdf_syntax_parser_ReadHexString_Test;
-
- static const int kParserMaxRecursionDepth = 64;
- static int s_CurrentRecursionDepth;
-
- uint32_t GetDirectNum();
- FX_BOOL GetNextChar(uint8_t& ch);
- FX_BOOL GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch);
- void GetNextWordInternal(bool* bIsNumber);
- bool IsWholeWord(FX_FILESIZE startpos,
- FX_FILESIZE limit,
- const CFX_ByteStringC& tag,
- FX_BOOL checkKeyword);
-
- CFX_ByteString ReadString();
- CFX_ByteString ReadHexString();
- unsigned int ReadEOLMarkers(FX_FILESIZE pos);
- CPDF_Stream* ReadStream(CPDF_Dictionary* pDict,
- uint32_t objnum,
- uint32_t gennum);
-
- CFX_ByteString MaybeIntern(const CFX_ByteString& str);
-
- FX_FILESIZE m_Pos;
- int m_MetadataObjnum;
- IFX_FileRead* m_pFileAccess;
- FX_FILESIZE m_HeaderOffset;
- FX_FILESIZE m_FileLen;
- uint8_t* m_pFileBuf;
- uint32_t m_BufSize;
- FX_FILESIZE m_BufOffset;
- std::unique_ptr<CPDF_CryptoHandler> m_pCryptoHandler;
- uint8_t m_WordBuffer[257];
- uint32_t m_WordSize;
- CFX_WeakPtr<CFX_ByteStringPool> m_pPool;
-};
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_SYNTAX_PARSER_H_
diff --git a/core/fpdfapi/fpdf_parser/cpdf_syntax_parser_unittest.cpp b/core/fpdfapi/fpdf_parser/cpdf_syntax_parser_unittest.cpp
deleted file mode 100644
index eb19652a0c..0000000000
--- a/core/fpdfapi/fpdf_parser/cpdf_syntax_parser_unittest.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <limits>
-#include <string>
-
-#include "core/fpdfapi/fpdf_parser/cpdf_parser.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h"
-#include "core/fxcrt/fx_ext.h"
-#include "core/fxcrt/fx_stream.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/utils/path_service.h"
-
-TEST(cpdf_syntax_parser, ReadHexString) {
- {
- // Empty string.
- uint8_t data[] = "";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 0, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("", parser.ReadHexString());
- EXPECT_EQ(0, parser.SavePos());
- }
-
- {
- // Blank string.
- uint8_t data[] = " ";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 2, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("", parser.ReadHexString());
- EXPECT_EQ(2, parser.SavePos());
- }
-
- {
- // Skips unknown characters.
- uint8_t data[] = "z12b";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("\x12\xb0", parser.ReadHexString());
- EXPECT_EQ(4, parser.SavePos());
- }
-
- {
- // Skips unknown characters.
- uint8_t data[] = "*<&*#$^&@1";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 10, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("\x10", parser.ReadHexString());
- EXPECT_EQ(10, parser.SavePos());
- }
-
- {
- // Skips unknown characters.
- uint8_t data[] = "\x80zab";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("\xab", parser.ReadHexString());
- EXPECT_EQ(4, parser.SavePos());
- }
-
- {
- // Skips unknown characters.
- uint8_t data[] = "\xffzab";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("\xab", parser.ReadHexString());
- EXPECT_EQ(4, parser.SavePos());
- }
-
- {
- // Regular conversion.
- uint8_t data[] = "1A2b>abcd";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 9, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
- EXPECT_EQ(5, parser.SavePos());
- }
-
- {
- // Position out of bounds.
- uint8_t data[] = "12ab>";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 5, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- parser.RestorePos(5);
- EXPECT_EQ("", parser.ReadHexString());
-
- parser.RestorePos(6);
- EXPECT_EQ("", parser.ReadHexString());
-
- parser.RestorePos(-1);
- EXPECT_EQ("", parser.ReadHexString());
-
- parser.RestorePos(std::numeric_limits<FX_FILESIZE>::max());
- EXPECT_EQ("", parser.ReadHexString());
-
- // Check string still parses when set to 0.
- parser.RestorePos(0);
- EXPECT_EQ("\x12\xab", parser.ReadHexString());
- }
-
- {
- // Missing ending >.
- uint8_t data[] = "1A2b";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 4, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
- EXPECT_EQ(4, parser.SavePos());
- }
-
- {
- // Missing ending >.
- uint8_t data[] = "12abz";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 5, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("\x12\xab", parser.ReadHexString());
- EXPECT_EQ(5, parser.SavePos());
- }
-
- {
- // Uneven number of bytes.
- uint8_t data[] = "1A2>asdf";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 8, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("\x1a\x20", parser.ReadHexString());
- EXPECT_EQ(4, parser.SavePos());
- }
-
- {
- // Uneven number of bytes.
- uint8_t data[] = "1A2zasdf";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 8, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("\x1a\x2a\xdf", parser.ReadHexString());
- EXPECT_EQ(8, parser.SavePos());
- }
-
- {
- // Just ending character.
- uint8_t data[] = ">";
- ScopedFileStream stream(FX_CreateMemoryStream(data, 1, FALSE));
-
- CPDF_SyntaxParser parser;
- parser.InitParser(stream.get(), 0);
- EXPECT_EQ("", parser.ReadHexString());
- EXPECT_EQ(1, parser.SavePos());
- }
-}
diff --git a/core/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp b/core/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp
deleted file mode 100644
index 4f172c0073..0000000000
--- a/core/fpdfapi/fpdf_parser/fpdf_parser_decode.cpp
+++ /dev/null
@@ -1,575 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h"
-
-#include <limits.h>
-
-#include <algorithm>
-#include <utility>
-#include <vector>
-
-#include "core/fpdfapi/cpdf_modulemgr.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h"
-#include "core/fxcodec/fx_codec.h"
-#include "core/fxcrt/fx_ext.h"
-#include "third_party/base/stl_util.h"
-
-namespace {
-
-const uint32_t kMaxStreamSize = 20 * 1024 * 1024;
-
-bool CheckFlateDecodeParams(int Colors, int BitsPerComponent, int Columns) {
- if (Colors < 0 || BitsPerComponent < 0 || Columns < 0)
- return false;
-
- int check = Columns;
- if (check > 0 && Colors > INT_MAX / check)
- return false;
-
- check *= Colors;
- if (check > 0 && BitsPerComponent > INT_MAX / check)
- return false;
-
- return check * BitsPerComponent <= INT_MAX - 7;
-}
-
-} // namespace
-
-const uint16_t PDFDocEncoding[256] = {
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
- 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011,
- 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x02d8, 0x02c7, 0x02c6,
- 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc, 0x0020, 0x0021, 0x0022, 0x0023,
- 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
- 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
- 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
- 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
- 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
- 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
- 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
- 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
- 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
- 0x007e, 0x0000, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192,
- 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018,
- 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, 0x0178,
- 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000, 0x20ac, 0x00a1,
- 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa,
- 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3,
- 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc,
- 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5,
- 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce,
- 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0,
- 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9,
- 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2,
- 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb,
- 0x00fc, 0x00fd, 0x00fe, 0x00ff};
-
-uint32_t A85Decode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size) {
- dest_size = 0;
- dest_buf = nullptr;
- if (src_size == 0)
- return 0;
-
- // Count legal characters and zeros.
- uint32_t zcount = 0;
- uint32_t pos = 0;
- while (pos < src_size) {
- uint8_t ch = src_buf[pos];
- if (ch == 'z') {
- zcount++;
- } else if ((ch < '!' || ch > 'u') && !PDFCharIsLineEnding(ch) &&
- ch != ' ' && ch != '\t') {
- break;
- }
- pos++;
- }
- // No content to decode.
- if (pos == 0)
- return 0;
-
- // Count the space needed to contain non-zero characters. The encoding ratio
- // of Ascii85 is 4:5.
- uint32_t space_for_non_zeroes = (pos - zcount) / 5 * 4 + 4;
- if (zcount > (UINT_MAX - space_for_non_zeroes) / 4) {
- return (uint32_t)-1;
- }
- dest_buf = FX_Alloc(uint8_t, zcount * 4 + space_for_non_zeroes);
- size_t state = 0;
- uint32_t res = 0;
- pos = dest_size = 0;
- while (pos < src_size) {
- uint8_t ch = src_buf[pos++];
- if (PDFCharIsLineEnding(ch) || ch == ' ' || ch == '\t')
- continue;
-
- if (ch == 'z') {
- FXSYS_memset(dest_buf + dest_size, 0, 4);
- state = 0;
- res = 0;
- dest_size += 4;
- } else if (ch >= '!' && ch <= 'u') {
- res = res * 85 + ch - 33;
- state++;
- if (state == 5) {
- for (size_t i = 0; i < 4; i++) {
- dest_buf[dest_size++] = (uint8_t)(res >> (3 - i) * 8);
- }
- state = 0;
- res = 0;
- }
- } else {
- // The end or illegal character.
- break;
- }
- }
- // Handle partial group.
- if (state) {
- for (size_t i = state; i < 5; i++)
- res = res * 85 + 84;
- for (size_t i = 0; i < state - 1; i++)
- dest_buf[dest_size++] = (uint8_t)(res >> (3 - i) * 8);
- }
- if (pos < src_size && src_buf[pos] == '>')
- pos++;
- return pos;
-}
-
-uint32_t HexDecode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size) {
- dest_size = 0;
- if (src_size == 0) {
- dest_buf = nullptr;
- return 0;
- }
-
- uint32_t i = 0;
- // Find the end of data.
- while (i < src_size && src_buf[i] != '>')
- i++;
-
- dest_buf = FX_Alloc(uint8_t, i / 2 + 1);
- bool bFirst = true;
- for (i = 0; i < src_size; i++) {
- uint8_t ch = src_buf[i];
- if (PDFCharIsLineEnding(ch) || ch == ' ' || ch == '\t')
- continue;
-
- if (ch == '>') {
- ++i;
- break;
- }
- if (!std::isxdigit(ch))
- continue;
-
- int digit = FXSYS_toHexDigit(ch);
- if (bFirst)
- dest_buf[dest_size] = digit * 16;
- else
- dest_buf[dest_size++] += digit;
-
- bFirst = !bFirst;
- }
- if (!bFirst)
- dest_size++;
- return i;
-}
-
-uint32_t RunLengthDecode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size) {
- uint32_t i = 0;
- dest_size = 0;
- while (i < src_size) {
- if (src_buf[i] == 128)
- break;
-
- uint32_t old = dest_size;
- if (src_buf[i] < 128) {
- dest_size += src_buf[i] + 1;
- if (dest_size < old)
- return FX_INVALID_OFFSET;
- i += src_buf[i] + 2;
- } else {
- dest_size += 257 - src_buf[i];
- if (dest_size < old)
- return FX_INVALID_OFFSET;
- i += 2;
- }
- }
- if (dest_size >= kMaxStreamSize)
- return FX_INVALID_OFFSET;
-
- dest_buf = FX_Alloc(uint8_t, dest_size);
- i = 0;
- int dest_count = 0;
- while (i < src_size) {
- if (src_buf[i] == 128)
- break;
-
- if (src_buf[i] < 128) {
- uint32_t copy_len = src_buf[i] + 1;
- uint32_t buf_left = src_size - i - 1;
- if (buf_left < copy_len) {
- uint32_t delta = copy_len - buf_left;
- copy_len = buf_left;
- FXSYS_memset(dest_buf + dest_count + copy_len, '\0', delta);
- }
- FXSYS_memcpy(dest_buf + dest_count, src_buf + i + 1, copy_len);
- dest_count += src_buf[i] + 1;
- i += src_buf[i] + 2;
- } else {
- int fill = 0;
- if (i < src_size - 1) {
- fill = src_buf[i + 1];
- }
- FXSYS_memset(dest_buf + dest_count, fill, 257 - src_buf[i]);
- dest_count += 257 - src_buf[i];
- i += 2;
- }
- }
-
- return std::min(i + 1, src_size);
-}
-
-CCodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(
- const uint8_t* src_buf,
- uint32_t src_size,
- int width,
- int height,
- const CPDF_Dictionary* pParams) {
- int K = 0;
- bool EndOfLine = false;
- bool ByteAlign = false;
- bool BlackIs1 = false;
- int Columns = 1728;
- int Rows = 0;
- if (pParams) {
- K = pParams->GetIntegerFor("K");
- EndOfLine = !!pParams->GetIntegerFor("EndOfLine");
- ByteAlign = !!pParams->GetIntegerFor("EncodedByteAlign");
- BlackIs1 = !!pParams->GetIntegerFor("BlackIs1");
- Columns = pParams->GetIntegerFor("Columns", 1728);
- Rows = pParams->GetIntegerFor("Rows");
- if (Rows > USHRT_MAX) {
- Rows = 0;
- }
- }
- return CPDF_ModuleMgr::Get()->GetFaxModule()->CreateDecoder(
- src_buf, src_size, width, height, K, EndOfLine, ByteAlign, BlackIs1,
- Columns, Rows);
-}
-
-CCodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(
- const uint8_t* src_buf,
- uint32_t src_size,
- int width,
- int height,
- int nComps,
- int bpc,
- const CPDF_Dictionary* pParams) {
- int predictor = 0;
- int Colors = 0, BitsPerComponent = 0, Columns = 0;
- if (pParams) {
- predictor = pParams->GetIntegerFor("Predictor");
- Colors = pParams->GetIntegerFor("Colors", 1);
- BitsPerComponent = pParams->GetIntegerFor("BitsPerComponent", 8);
- Columns = pParams->GetIntegerFor("Columns", 1);
- if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) {
- return nullptr;
- }
- }
- return CPDF_ModuleMgr::Get()->GetFlateModule()->CreateDecoder(
- src_buf, src_size, width, height, nComps, bpc, predictor, Colors,
- BitsPerComponent, Columns);
-}
-
-uint32_t FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW,
- const uint8_t* src_buf,
- uint32_t src_size,
- CPDF_Dictionary* pParams,
- uint32_t estimated_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size) {
- int predictor = 0;
- FX_BOOL bEarlyChange = TRUE;
- int Colors = 0, BitsPerComponent = 0, Columns = 0;
- if (pParams) {
- predictor = pParams->GetIntegerFor("Predictor");
- bEarlyChange = pParams->GetIntegerFor("EarlyChange", 1);
- Colors = pParams->GetIntegerFor("Colors", 1);
- BitsPerComponent = pParams->GetIntegerFor("BitsPerComponent", 8);
- Columns = pParams->GetIntegerFor("Columns", 1);
- if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) {
- return (uint32_t)-1;
- }
- }
- return CPDF_ModuleMgr::Get()->GetFlateModule()->FlateOrLZWDecode(
- bLZW, src_buf, src_size, bEarlyChange, predictor, Colors,
- BitsPerComponent, Columns, estimated_size, dest_buf, dest_size);
-}
-
-FX_BOOL PDF_DataDecode(const uint8_t* src_buf,
- uint32_t src_size,
- const CPDF_Dictionary* pDict,
- uint8_t*& dest_buf,
- uint32_t& dest_size,
- CFX_ByteString& ImageEncoding,
- CPDF_Dictionary*& pImageParms,
- uint32_t last_estimated_size,
- FX_BOOL bImageAcc) {
- CPDF_Object* pDecoder = pDict ? pDict->GetDirectObjectFor("Filter") : nullptr;
- if (!pDecoder || (!pDecoder->IsArray() && !pDecoder->IsName()))
- return FALSE;
-
- CPDF_Object* pParams =
- pDict ? pDict->GetDirectObjectFor("DecodeParms") : nullptr;
-
- std::vector<std::pair<CFX_ByteString, CPDF_Object*>> DecoderArray;
- if (CPDF_Array* pDecoders = pDecoder->AsArray()) {
- CPDF_Array* pParamsArray = ToArray(pParams);
- for (size_t i = 0; i < pDecoders->GetCount(); i++) {
- DecoderArray.push_back(
- {pDecoders->GetStringAt(i),
- pParamsArray ? pParamsArray->GetDictAt(i) : nullptr});
- }
- } else {
- DecoderArray.push_back(
- {pDecoder->GetString(), pParams ? pParams->GetDict() : nullptr});
- }
- uint8_t* last_buf = const_cast<uint8_t*>(src_buf);
- uint32_t last_size = src_size;
- int nSize = pdfium::CollectionSize<int>(DecoderArray);
- for (int i = 0; i < nSize; i++) {
- int estimated_size = i == nSize - 1 ? last_estimated_size : 0;
- CFX_ByteString decoder = DecoderArray[i].first;
- CPDF_Dictionary* pParam = ToDictionary(DecoderArray[i].second);
- uint8_t* new_buf = nullptr;
- uint32_t new_size = (uint32_t)-1;
- int offset = -1;
- if (decoder == "FlateDecode" || decoder == "Fl") {
- if (bImageAcc && i == nSize - 1) {
- ImageEncoding = "FlateDecode";
- dest_buf = (uint8_t*)last_buf;
- dest_size = last_size;
- pImageParms = pParam;
- return TRUE;
- }
- offset = FPDFAPI_FlateOrLZWDecode(FALSE, last_buf, last_size, pParam,
- estimated_size, new_buf, new_size);
- } else if (decoder == "LZWDecode" || decoder == "LZW") {
- offset = FPDFAPI_FlateOrLZWDecode(TRUE, last_buf, last_size, pParam,
- estimated_size, new_buf, new_size);
- } else if (decoder == "ASCII85Decode" || decoder == "A85") {
- offset = A85Decode(last_buf, last_size, new_buf, new_size);
- } else if (decoder == "ASCIIHexDecode" || decoder == "AHx") {
- offset = HexDecode(last_buf, last_size, new_buf, new_size);
- } else if (decoder == "RunLengthDecode" || decoder == "RL") {
- if (bImageAcc && i == nSize - 1) {
- ImageEncoding = "RunLengthDecode";
- dest_buf = (uint8_t*)last_buf;
- dest_size = last_size;
- pImageParms = pParam;
- return TRUE;
- }
- offset = RunLengthDecode(last_buf, last_size, new_buf, new_size);
- } else if (decoder == "Crypt") {
- continue;
- } else {
- // If we get here, assume it's an image decoder.
- if (decoder == "DCT") {
- decoder = "DCTDecode";
- } else if (decoder == "CCF") {
- decoder = "CCITTFaxDecode";
- }
- ImageEncoding = decoder;
- pImageParms = pParam;
- dest_buf = (uint8_t*)last_buf;
- dest_size = last_size;
- if (CPDF_Array* pDecoders = pDecoder->AsArray())
- pDecoders->RemoveAt(i + 1, pDecoders->GetCount() - i - 1);
- return TRUE;
- }
- if (last_buf != src_buf) {
- FX_Free(last_buf);
- }
- if (offset == -1) {
- FX_Free(new_buf);
- return FALSE;
- }
- last_buf = new_buf;
- last_size = new_size;
- }
- ImageEncoding = "";
- pImageParms = nullptr;
- dest_buf = last_buf;
- dest_size = last_size;
- return TRUE;
-}
-
-CFX_WideString PDF_DecodeText(const uint8_t* src_data, uint32_t src_len) {
- CFX_WideString result;
- if (src_len >= 2 && ((src_data[0] == 0xfe && src_data[1] == 0xff) ||
- (src_data[0] == 0xff && src_data[1] == 0xfe))) {
- bool bBE = src_data[0] == 0xfe;
- uint32_t max_chars = (src_len - 2) / 2;
- if (!max_chars) {
- return result;
- }
- if (src_data[0] == 0xff) {
- bBE = !src_data[2];
- }
- FX_WCHAR* dest_buf = result.GetBuffer(max_chars);
- const uint8_t* uni_str = src_data + 2;
- int dest_pos = 0;
- for (uint32_t i = 0; i < max_chars * 2; i += 2) {
- uint16_t unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1])
- : (uni_str[i + 1] << 8 | uni_str[i]);
- if (unicode == 0x1b) {
- i += 2;
- while (i < max_chars * 2) {
- uint16_t unicode2 = bBE ? (uni_str[i] << 8 | uni_str[i + 1])
- : (uni_str[i + 1] << 8 | uni_str[i]);
- i += 2;
- if (unicode2 == 0x1b)
- break;
- }
- } else {
- dest_buf[dest_pos++] = unicode;
- }
- }
- result.ReleaseBuffer(dest_pos);
- } else {
- FX_WCHAR* dest_buf = result.GetBuffer(src_len);
- for (uint32_t i = 0; i < src_len; i++)
- dest_buf[i] = PDFDocEncoding[src_data[i]];
- result.ReleaseBuffer(src_len);
- }
- return result;
-}
-
-CFX_WideString PDF_DecodeText(const CFX_ByteString& bstr) {
- return PDF_DecodeText((const uint8_t*)bstr.c_str(), bstr.GetLength());
-}
-
-CFX_ByteString PDF_EncodeText(const FX_WCHAR* pString, int len) {
- if (len == -1) {
- len = FXSYS_wcslen(pString);
- }
- CFX_ByteString result;
- FX_CHAR* dest_buf1 = result.GetBuffer(len);
- int i;
- for (i = 0; i < len; i++) {
- int code;
- for (code = 0; code < 256; code++)
- if (PDFDocEncoding[code] == pString[i]) {
- break;
- }
- if (code == 256) {
- break;
- }
- dest_buf1[i] = code;
- }
- result.ReleaseBuffer(i);
- if (i == len) {
- return result;
- }
-
- if (len > INT_MAX / 2 - 1) {
- result.ReleaseBuffer(0);
- return result;
- }
-
- int encLen = len * 2 + 2;
-
- uint8_t* dest_buf2 = (uint8_t*)result.GetBuffer(encLen);
- dest_buf2[0] = 0xfe;
- dest_buf2[1] = 0xff;
- dest_buf2 += 2;
- for (int j = 0; j < len; j++) {
- *dest_buf2++ = pString[i] >> 8;
- *dest_buf2++ = (uint8_t)pString[j];
- }
- result.ReleaseBuffer(encLen);
- return result;
-}
-
-CFX_ByteString PDF_EncodeText(const CFX_WideString& str) {
- return PDF_EncodeText(str.c_str(), str.GetLength());
-}
-
-CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, FX_BOOL bHex) {
- CFX_ByteTextBuf result;
- int srclen = src.GetLength();
- if (bHex) {
- result.AppendChar('<');
- for (int i = 0; i < srclen; i++) {
- result.AppendChar("0123456789ABCDEF"[src[i] / 16]);
- result.AppendChar("0123456789ABCDEF"[src[i] % 16]);
- }
- result.AppendChar('>');
- return result.MakeString();
- }
- result.AppendChar('(');
- for (int i = 0; i < srclen; i++) {
- uint8_t ch = src[i];
- if (ch == 0x0a) {
- result << "\\n";
- continue;
- }
- if (ch == 0x0d) {
- result << "\\r";
- continue;
- }
- if (ch == ')' || ch == '\\' || ch == '(')
- result.AppendChar('\\');
- result.AppendChar(ch);
- }
- result.AppendChar(')');
- return result.MakeString();
-}
-
-bool FlateEncode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t** dest_buf,
- uint32_t* dest_size) {
- CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
- return pEncoders &&
- pEncoders->GetFlateModule()->Encode(src_buf, src_size, dest_buf,
- dest_size);
-}
-
-bool PngEncode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t** dest_buf,
- uint32_t* dest_size) {
- CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
- return pEncoders &&
- pEncoders->GetFlateModule()->PngEncode(src_buf, src_size, dest_buf,
- dest_size);
-}
-
-uint32_t FlateDecode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size) {
- CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
- if (pEncoders) {
- return pEncoders->GetFlateModule()->FlateOrLZWDecode(
- FALSE, src_buf, src_size, FALSE, 0, 0, 0, 0, 0, dest_buf, dest_size);
- }
- return 0;
-}
diff --git a/core/fpdfapi/fpdf_parser/fpdf_parser_decode.h b/core/fpdfapi/fpdf_parser/fpdf_parser_decode.h
deleted file mode 100644
index fab148bc14..0000000000
--- a/core/fpdfapi/fpdf_parser/fpdf_parser_decode.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_FPDF_PARSER_DECODE_H_
-#define CORE_FPDFAPI_FPDF_PARSER_FPDF_PARSER_DECODE_H_
-
-#include "core/fxcrt/fx_basic.h"
-
-class CPDF_Dictionary;
-
-// Indexed by 8-bit char code, contains unicode code points.
-extern const uint16_t PDFDocEncoding[256];
-
-CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& orig);
-CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig);
-CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig);
-CFX_ByteString PDF_EncodeString(const CFX_ByteString& src,
- FX_BOOL bHex = FALSE);
-CFX_WideString PDF_DecodeText(const uint8_t* pData, uint32_t size);
-CFX_WideString PDF_DecodeText(const CFX_ByteString& bstr);
-CFX_ByteString PDF_EncodeText(const FX_WCHAR* pString, int len = -1);
-CFX_ByteString PDF_EncodeText(const CFX_WideString& str);
-
-bool FlateEncode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t** dest_buf,
- uint32_t* dest_size);
-
-// This used to have more parameters like the predictor and bpc, but there was
-// only one caller, so the interface has been simplified, the values are hard
-// coded, and dead code has been removed.
-bool PngEncode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t** dest_buf,
- uint32_t* dest_size);
-
-uint32_t FlateDecode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size);
-uint32_t RunLengthDecode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size);
-
-// Public for testing.
-uint32_t A85Decode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size);
-// Public for testing.
-uint32_t HexDecode(const uint8_t* src_buf,
- uint32_t src_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size);
-// Public for testing.
-uint32_t FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW,
- const uint8_t* src_buf,
- uint32_t src_size,
- CPDF_Dictionary* pParams,
- uint32_t estimated_size,
- uint8_t*& dest_buf,
- uint32_t& dest_size);
-FX_BOOL PDF_DataDecode(const uint8_t* src_buf,
- uint32_t src_size,
- const CPDF_Dictionary* pDict,
- uint8_t*& dest_buf,
- uint32_t& dest_size,
- CFX_ByteString& ImageEncoding,
- CPDF_Dictionary*& pImageParms,
- uint32_t estimated_size,
- FX_BOOL bImageAcc);
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_FPDF_PARSER_DECODE_H_
diff --git a/core/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp b/core/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp
deleted file mode 100644
index ab0dc4ea3f..0000000000
--- a/core/fpdfapi/fpdf_parser/fpdf_parser_decode_embeddertest.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2015 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h"
-
-#include <cstring>
-#include <string>
-
-#include "core/fxcrt/fx_basic.h"
-#include "testing/embedder_test.h"
-#include "testing/fx_string_testhelpers.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/test_support.h"
-
-class FPDFParserDecodeEmbeddertest : public EmbedderTest {};
-
-// NOTE: python's zlib.compress() and zlib.decompress() may be useful for
-// external validation of the FlateEncode/FlateDecode test cases.
-
-TEST_F(FPDFParserDecodeEmbeddertest, FlateEncode) {
- pdfium::StrFuncTestData flate_encode_cases[] = {
- STR_IN_OUT_CASE("", "\x78\x9c\x03\x00\x00\x00\x00\x01"),
- STR_IN_OUT_CASE(" ", "\x78\x9c\x53\x00\x00\x00\x21\x00\x21"),
- STR_IN_OUT_CASE("123", "\x78\x9c\x33\x34\x32\x06\x00\01\x2d\x00\x97"),
- STR_IN_OUT_CASE("\x00\xff", "\x78\x9c\x63\xf8\x0f\x00\x01\x01\x01\x00"),
- STR_IN_OUT_CASE(
- "1 0 0 -1 29 763 cm\n0 0 555 735 re\nW n\nq\n0 0 555 734.394 re\n"
- "W n\nq\n0.8009 0 0 0.8009 0 0 cm\n1 1 1 RG 1 1 1 rg\n/G0 gs\n"
- "0 0 693 917 re\nf\nQ\nQ\n",
- "\x78\x9c\x33\x54\x30\x00\x42\x5d\x43\x05\x23\x4b\x05\x73\x33\x63"
- "\x85\xe4\x5c\x2e\x90\x80\xa9\xa9\xa9\x82\xb9\xb1\xa9\x42\x51\x2a"
- "\x57\xb8\x42\x1e\x57\x21\x92\xa0\x89\x9e\xb1\xa5\x09\x92\x84\x9e"
- "\x85\x81\x81\x25\xd8\x14\x24\x26\xd0\x18\x43\x05\x10\x0c\x72\x57"
- "\x80\x30\x8a\xd2\xb9\xf4\xdd\x0d\x14\xd2\x8b\xc1\x46\x99\x59\x1a"
- "\x2b\x58\x1a\x9a\x83\x8c\x49\xe3\x0a\x04\x42\x00\x37\x4c\x1b\x42"),
- };
-
- for (size_t i = 0; i < FX_ArraySize(flate_encode_cases); ++i) {
- const pdfium::StrFuncTestData& data = flate_encode_cases[i];
- unsigned char* buf = nullptr;
- unsigned int buf_size;
- EXPECT_TRUE(FlateEncode(data.input, data.input_size, &buf, &buf_size));
- ASSERT_TRUE(buf);
- EXPECT_EQ(std::string((const char*)data.expected, data.expected_size),
- std::string((const char*)buf, buf_size))
- << " for case " << i;
- FX_Free(buf);
- }
-}
-
-TEST_F(FPDFParserDecodeEmbeddertest, FlateDecode) {
- pdfium::DecodeTestData flate_decode_cases[] = {
- STR_IN_OUT_CASE("", "", 0),
- STR_IN_OUT_CASE("preposterous nonsense", "", 2),
- STR_IN_OUT_CASE("\x78\x9c\x03\x00\x00\x00\x00\x01", "", 8),
- STR_IN_OUT_CASE("\x78\x9c\x53\x00\x00\x00\x21\x00\x21", " ", 9),
- STR_IN_OUT_CASE("\x78\x9c\x33\x34\x32\x06\x00\01\x2d\x00\x97", "123", 11),
- STR_IN_OUT_CASE("\x78\x9c\x63\xf8\x0f\x00\x01\x01\x01\x00", "\x00\xff",
- 10),
- STR_IN_OUT_CASE(
- "\x78\x9c\x33\x54\x30\x00\x42\x5d\x43\x05\x23\x4b\x05\x73\x33\x63"
- "\x85\xe4\x5c\x2e\x90\x80\xa9\xa9\xa9\x82\xb9\xb1\xa9\x42\x51\x2a"
- "\x57\xb8\x42\x1e\x57\x21\x92\xa0\x89\x9e\xb1\xa5\x09\x92\x84\x9e"
- "\x85\x81\x81\x25\xd8\x14\x24\x26\xd0\x18\x43\x05\x10\x0c\x72\x57"
- "\x80\x30\x8a\xd2\xb9\xf4\xdd\x0d\x14\xd2\x8b\xc1\x46\x99\x59\x1a"
- "\x2b\x58\x1a\x9a\x83\x8c\x49\xe3\x0a\x04\x42\x00\x37\x4c\x1b\x42",
- "1 0 0 -1 29 763 cm\n0 0 555 735 re\nW n\nq\n0 0 555 734.394 re\n"
- "W n\nq\n0.8009 0 0 0.8009 0 0 cm\n1 1 1 RG 1 1 1 rg\n/G0 gs\n"
- "0 0 693 917 re\nf\nQ\nQ\n",
- 96),
- };
-
- for (size_t i = 0; i < FX_ArraySize(flate_decode_cases); ++i) {
- const pdfium::DecodeTestData& data = flate_decode_cases[i];
- unsigned char* result = nullptr;
- unsigned int result_size;
- EXPECT_EQ(data.processed_size,
- FlateDecode(data.input, data.input_size, result, result_size))
- << " for case " << i;
- ASSERT_TRUE(result);
- EXPECT_EQ(std::string((const char*)data.expected, data.expected_size),
- std::string((const char*)result, result_size))
- << " for case " << i;
- FX_Free(result);
- }
-}
-
-TEST_F(FPDFParserDecodeEmbeddertest, Bug_552046) {
- // Tests specifying multiple image filters for a stream. Should not cause a
- // crash when rendered.
- EXPECT_TRUE(OpenDocument("bug_552046.pdf"));
- FPDF_PAGE page = LoadPage(0);
- FPDF_BITMAP bitmap = RenderPage(page);
- FPDFBitmap_Destroy(bitmap);
- UnloadPage(page);
-}
-
-TEST_F(FPDFParserDecodeEmbeddertest, Bug_555784) {
- // Tests bad input to the run length decoder that caused a heap overflow.
- // Should not cause a crash when rendered.
- EXPECT_TRUE(OpenDocument("bug_555784.pdf"));
- FPDF_PAGE page = LoadPage(0);
- FPDF_BITMAP bitmap = RenderPage(page);
- FPDFBitmap_Destroy(bitmap);
- UnloadPage(page);
-}
-
-TEST_F(FPDFParserDecodeEmbeddertest, Bug_455199) {
- // Tests object numbers with a value > 01000000.
- // Should open successfully.
- EXPECT_TRUE(OpenDocument("bug_455199.pdf"));
- FPDF_PAGE page = LoadPage(0);
- FPDF_BITMAP bitmap = RenderPage(page);
- FPDFBitmap_Destroy(bitmap);
- UnloadPage(page);
-}
diff --git a/core/fpdfapi/fpdf_parser/fpdf_parser_decode_unittest.cpp b/core/fpdfapi/fpdf_parser/fpdf_parser_decode_unittest.cpp
deleted file mode 100644
index 469ca4f150..0000000000
--- a/core/fpdfapi/fpdf_parser/fpdf_parser_decode_unittest.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2015 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/test_support.h"
-
-TEST(fpdf_parser_decode, A85Decode) {
- pdfium::DecodeTestData test_data[] = {
- // Empty src string.
- STR_IN_OUT_CASE("", "", 0),
- // Empty content in src string.
- STR_IN_OUT_CASE("~>", "", 0),
- // Regular conversion.
- STR_IN_OUT_CASE("FCfN8~>", "test", 7),
- // End at the ending mark.
- STR_IN_OUT_CASE("FCfN8~>FCfN8", "test", 7),
- // Skip whitespaces.
- STR_IN_OUT_CASE("\t F C\r\n \tf N 8 ~>", "test", 17),
- // No ending mark.
- STR_IN_OUT_CASE("@3B0)DJj_BF*)>@Gp#-s", "a funny story :)", 20),
- // Non-multiple length.
- STR_IN_OUT_CASE("12A", "2k", 3),
- // Stop at unknown characters.
- STR_IN_OUT_CASE("FCfN8FCfN8vw", "testtest", 11),
- };
- for (size_t i = 0; i < FX_ArraySize(test_data); ++i) {
- pdfium::DecodeTestData* ptr = &test_data[i];
- uint8_t* result = nullptr;
- uint32_t result_size = 0;
- EXPECT_EQ(ptr->processed_size,
- A85Decode(ptr->input, ptr->input_size, result, result_size))
- << "for case " << i;
- ASSERT_EQ(ptr->expected_size, result_size);
- for (size_t j = 0; j < result_size; ++j) {
- EXPECT_EQ(ptr->expected[j], result[j]) << "for case " << i << " char "
- << j;
- }
- FX_Free(result);
- }
-}
-
-TEST(fpdf_parser_decode, HexDecode) {
- pdfium::DecodeTestData test_data[] = {
- // Empty src string.
- STR_IN_OUT_CASE("", "", 0),
- // Empty content in src string.
- STR_IN_OUT_CASE(">", "", 1),
- // Only whitespaces in src string.
- STR_IN_OUT_CASE("\t \r\n>", "", 7),
- // Regular conversion.
- STR_IN_OUT_CASE("12Ac>zzz", "\x12\xac", 5),
- // Skip whitespaces.
- STR_IN_OUT_CASE("12 Ac\t02\r\nBF>zzz>", "\x12\xac\x02\xbf", 13),
- // Non-multiple length.
- STR_IN_OUT_CASE("12A>zzz", "\x12\xa0", 4),
- // Skips unknown characters.
- STR_IN_OUT_CASE("12tk \tAc>zzz", "\x12\xac", 10),
- // No ending mark.
- STR_IN_OUT_CASE("12AcED3c3456", "\x12\xac\xed\x3c\x34\x56", 12),
- };
- for (size_t i = 0; i < FX_ArraySize(test_data); ++i) {
- pdfium::DecodeTestData* ptr = &test_data[i];
- uint8_t* result = nullptr;
- uint32_t result_size = 0;
- EXPECT_EQ(ptr->processed_size,
- HexDecode(ptr->input, ptr->input_size, result, result_size))
- << "for case " << i;
- ASSERT_EQ(ptr->expected_size, result_size);
- for (size_t j = 0; j < result_size; ++j) {
- EXPECT_EQ(ptr->expected[j], result[j]) << "for case " << i << " char "
- << j;
- }
- FX_Free(result);
- }
-}
diff --git a/core/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp b/core/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp
deleted file mode 100644
index 304cb4a7e6..0000000000
--- a/core/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h"
-
-#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_number.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h"
-#include "core/fpdfapi/fpdf_parser/cpdf_string.h"
-#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h"
-#include "core/fxcrt/fx_ext.h"
-
-// Indexed by 8-bit character code, contains either:
-// 'W' - for whitespace: NUL, TAB, CR, LF, FF, SPACE, 0x80, 0xff
-// 'N' - for numeric: 0123456789+-.
-// 'D' - for delimiter: %()/<>[]{}
-// 'R' - otherwise.
-const char PDF_CharType[256] = {
- // NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO
- // SI
- 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W', 'W', 'R', 'W', 'W', 'R',
- 'R',
-
- // DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS
- // US
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
- 'R',
-
- // SP ! " # $ % & ยด ( ) * + , - .
- // /
- 'W', 'R', 'R', 'R', 'R', 'D', 'R', 'R', 'D', 'D', 'R', 'N', 'R', 'N', 'N',
- 'D',
-
- // 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
- 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'R', 'R', 'D', 'R', 'D',
- 'R',
-
- // @ A B C D E F G H I J K L M N O
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
- 'R',
-
- // P Q R S T U V W X Y Z [ \ ] ^ _
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R',
- 'R',
-
- // ` a b c d e f g h i j k l m n o
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
- 'R',
-
- // p q r s t u v w x y z { | } ~
- // DEL
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R',
- 'R',
-
- 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
- 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W'};
-
-int32_t GetHeaderOffset(IFX_FileRead* pFile) {
- const size_t kBufSize = 4;
- uint8_t buf[kBufSize];
- for (int32_t offset = 0; offset <= 1024; ++offset) {
- if (!pFile->ReadBlock(buf, offset, kBufSize))
- return -1;
-
- if (memcmp(buf, "%PDF", 4) == 0)
- return offset;
- }
- return -1;
-}
-
-int32_t GetDirectInteger(CPDF_Dictionary* pDict, const CFX_ByteString& key) {
- CPDF_Number* pObj = ToNumber(pDict->GetObjectFor(key));
- return pObj ? pObj->GetInteger() : 0;
-}
-
-CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) {
- if (bstr.Find('#') == -1)
- return CFX_ByteString(bstr);
-
- int size = bstr.GetLength();
- CFX_ByteString result;
- FX_CHAR* pDestStart = result.GetBuffer(size);
- FX_CHAR* pDest = pDestStart;
- for (int i = 0; i < size; i++) {
- if (bstr[i] == '#' && i < size - 2) {
- *pDest++ =
- FXSYS_toHexDigit(bstr[i + 1]) * 16 + FXSYS_toHexDigit(bstr[i + 2]);
- i += 2;
- } else {
- *pDest++ = bstr[i];
- }
- }
- result.ReleaseBuffer((FX_STRSIZE)(pDest - pDestStart));
- return result;
-}
-
-CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig) {
- if (orig.Find('#') == -1)
- return orig;
- return PDF_NameDecode(orig.AsStringC());
-}
-
-CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig) {
- uint8_t* src_buf = (uint8_t*)orig.c_str();
- int src_len = orig.GetLength();
- int dest_len = 0;
- int i;
- for (i = 0; i < src_len; i++) {
- uint8_t ch = src_buf[i];
- if (ch >= 0x80 || PDFCharIsWhitespace(ch) || ch == '#' ||
- PDFCharIsDelimiter(ch)) {
- dest_len += 3;
- } else {
- dest_len++;
- }
- }
- if (dest_len == src_len)
- return orig;
-
- CFX_ByteString res;
- FX_CHAR* dest_buf = res.GetBuffer(dest_len);
- dest_len = 0;
- for (i = 0; i < src_len; i++) {
- uint8_t ch = src_buf[i];
- if (ch >= 0x80 || PDFCharIsWhitespace(ch) || ch == '#' ||
- PDFCharIsDelimiter(ch)) {
- dest_buf[dest_len++] = '#';
- dest_buf[dest_len++] = "0123456789ABCDEF"[ch / 16];
- dest_buf[dest_len++] = "0123456789ABCDEF"[ch % 16];
- } else {
- dest_buf[dest_len++] = ch;
- }
- }
- dest_buf[dest_len] = 0;
- res.ReleaseBuffer();
- return res;
-}
-
-CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj) {
- if (!pObj) {
- buf << " null";
- return buf;
- }
- switch (pObj->GetType()) {
- case CPDF_Object::NULLOBJ:
- buf << " null";
- break;
- case CPDF_Object::BOOLEAN:
- case CPDF_Object::NUMBER:
- buf << " " << pObj->GetString();
- break;
- case CPDF_Object::STRING:
- buf << PDF_EncodeString(pObj->GetString(), pObj->AsString()->IsHex());
- break;
- case CPDF_Object::NAME: {
- CFX_ByteString str = pObj->GetString();
- buf << "/" << PDF_NameEncode(str);
- break;
- }
- case CPDF_Object::REFERENCE: {
- buf << " " << pObj->AsReference()->GetRefObjNum() << " 0 R ";
- break;
- }
- case CPDF_Object::ARRAY: {
- const CPDF_Array* p = pObj->AsArray();
- buf << "[";
- for (size_t i = 0; i < p->GetCount(); i++) {
- CPDF_Object* pElement = p->GetObjectAt(i);
- if (pElement && pElement->GetObjNum()) {
- buf << " " << pElement->GetObjNum() << " 0 R";
- } else {
- buf << pElement;
- }
- }
- buf << "]";
- break;
- }
- case CPDF_Object::DICTIONARY: {
- const CPDF_Dictionary* p = pObj->AsDictionary();
- buf << "<<";
- for (const auto& it : *p) {
- const CFX_ByteString& key = it.first;
- CPDF_Object* pValue = it.second;
- buf << "/" << PDF_NameEncode(key);
- if (pValue && pValue->GetObjNum()) {
- buf << " " << pValue->GetObjNum() << " 0 R ";
- } else {
- buf << pValue;
- }
- }
- buf << ">>";
- break;
- }
- case CPDF_Object::STREAM: {
- const CPDF_Stream* p = pObj->AsStream();
- buf << p->GetDict() << "stream\r\n";
- CPDF_StreamAcc acc;
- acc.LoadAllData(p, TRUE);
- buf.AppendBlock(acc.GetData(), acc.GetSize());
- buf << "\r\nendstream";
- break;
- }
- default:
- ASSERT(FALSE);
- break;
- }
- return buf;
-}
diff --git a/core/fpdfapi/fpdf_parser/fpdf_parser_utility.h b/core/fpdfapi/fpdf_parser/fpdf_parser_utility.h
deleted file mode 100644
index 98bffa7e7c..0000000000
--- a/core/fpdfapi/fpdf_parser/fpdf_parser_utility.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_FPDF_PARSER_FPDF_PARSER_UTILITY_H_
-#define CORE_FPDFAPI_FPDF_PARSER_FPDF_PARSER_UTILITY_H_
-
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-
-class IFX_FileRead;
-class CPDF_Dictionary;
-
-// Use the accessors below instead of directly accessing PDF_CharType.
-extern const char PDF_CharType[256];
-
-inline bool PDFCharIsWhitespace(uint8_t c) {
- return PDF_CharType[c] == 'W';
-}
-inline bool PDFCharIsNumeric(uint8_t c) {
- return PDF_CharType[c] == 'N';
-}
-inline bool PDFCharIsDelimiter(uint8_t c) {
- return PDF_CharType[c] == 'D';
-}
-inline bool PDFCharIsOther(uint8_t c) {
- return PDF_CharType[c] == 'R';
-}
-
-inline bool PDFCharIsLineEnding(uint8_t c) {
- return c == '\r' || c == '\n';
-}
-
-int32_t GetHeaderOffset(IFX_FileRead* pFile);
-int32_t GetDirectInteger(CPDF_Dictionary* pDict, const CFX_ByteString& key);
-
-#endif // CORE_FPDFAPI_FPDF_PARSER_FPDF_PARSER_UTILITY_H_