summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortsepez <tsepez@chromium.org>2016-11-16 17:31:18 -0800
committerCommit bot <commit-bot@chromium.org>2016-11-16 17:31:18 -0800
commit5913a6ca71c85401e3f5317758d44a9fc4a667b2 (patch)
tree388ad0bd98b44a47c251568e198e2c3c231c7d30
parentcc4d0a44f3025821f88f3ed1ee78dfdc416487c7 (diff)
downloadpdfium-5913a6ca71c85401e3f5317758d44a9fc4a667b2.tar.xz
Make CPDF_Object subclass constructors intern strings
Make CDPF_Arrays intern the object they create. Allow passing nullptr as a CFX_WeakPtr shortcut as well. Review-Url: https://codereview.chromium.org/2509123002
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp3
-rw-r--r--core/fpdfapi/font/cpdf_fontencoding.cpp6
-rw-r--r--core/fpdfapi/page/cpdf_docpagedata.cpp3
-rw-r--r--core/fpdfapi/page/cpdf_streamcontentparser.cpp9
-rw-r--r--core/fpdfapi/page/cpdf_streamparser.cpp6
-rw-r--r--core/fpdfapi/parser/cfdf_document.cpp3
-rw-r--r--core/fpdfapi/parser/cpdf_array.cpp3
-rw-r--r--core/fpdfapi/parser/cpdf_array.h35
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.cpp4
-rw-r--r--core/fpdfapi/parser/cpdf_document.cpp20
-rw-r--r--core/fpdfapi/parser/cpdf_indirect_object_holder.h16
-rw-r--r--core/fpdfapi/parser/cpdf_name.cpp9
-rw-r--r--core/fpdfapi/parser/cpdf_name.h4
-rw-r--r--core/fpdfapi/parser/cpdf_object.h9
-rw-r--r--core/fpdfapi/parser/cpdf_object_unittest.cpp15
-rw-r--r--core/fpdfapi/parser/cpdf_string.cpp14
-rw-r--r--core/fpdfapi/parser/cpdf_string.h6
-rw-r--r--core/fpdfapi/parser/cpdf_syntax_parser.cpp22
-rw-r--r--core/fpdfapi/parser/cpdf_syntax_parser.h1
-rw-r--r--core/fpdfdoc/cpdf_filespec_unittest.cpp2
-rw-r--r--core/fpdfdoc/cpdf_interform.cpp3
-rw-r--r--core/fpdfdoc/cpvt_generateap.cpp5
-rw-r--r--core/fxcrt/cfx_weak_ptr.h4
-rw-r--r--fpdfsdk/formfiller/cba_fontmap.cpp3
-rw-r--r--fpdfsdk/fpdfdoc_unittest.cpp6
-rw-r--r--fpdfsdk/fpdfeditpage.cpp6
-rw-r--r--fpdfsdk/fpdfppo.cpp10
27 files changed, 145 insertions, 82 deletions
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 8e7e7b3504..80450a8025 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -62,8 +62,7 @@ CFX_ByteString CPDF_PageContentGenerator::RealizeResource(
const CFX_ByteString& bsType) {
ASSERT(dwResourceObjNum);
if (!m_pPage->m_pResources) {
- m_pPage->m_pResources = m_pDocument->NewIndirect<CPDF_Dictionary>(
- m_pDocument->GetByteStringPool());
+ m_pPage->m_pResources = m_pDocument->NewIndirect<CPDF_Dictionary>();
m_pPage->m_pFormDict->SetReferenceFor("Resources", m_pDocument,
m_pPage->m_pResources);
}
diff --git a/core/fpdfapi/font/cpdf_fontencoding.cpp b/core/fpdfapi/font/cpdf_fontencoding.cpp
index 3537330def..da607e6aa8 100644
--- a/core/fpdfapi/font/cpdf_fontencoding.cpp
+++ b/core/fpdfapi/font/cpdf_fontencoding.cpp
@@ -1689,13 +1689,13 @@ CPDF_Object* CPDF_FontEncoding::Realize(CFX_WeakPtr<CFX_ByteStringPool> pPool) {
}
if (predefined) {
if (predefined == PDFFONT_ENCODING_WINANSI) {
- return new CPDF_Name(pPool->Intern("WinAnsiEncoding"));
+ return new CPDF_Name(pPool, "WinAnsiEncoding");
}
if (predefined == PDFFONT_ENCODING_MACROMAN) {
- return new CPDF_Name(pPool->Intern("MacRomanEncoding"));
+ return new CPDF_Name(pPool, "MacRomanEncoding");
}
if (predefined == PDFFONT_ENCODING_MACEXPERT) {
- return new CPDF_Name(pPool->Intern("MacExpertEncoding"));
+ return new CPDF_Name(pPool, "MacExpertEncoding");
}
return nullptr;
}
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index 2c9f4bb1f7..b849bc4107 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -175,8 +175,7 @@ CPDF_Font* CPDF_DocPageData::GetStandardFont(const CFX_ByteString& fontName,
return fontData->AddRef();
}
- CPDF_Dictionary* pDict =
- m_pPDFDoc->NewIndirect<CPDF_Dictionary>(m_pPDFDoc->GetByteStringPool());
+ CPDF_Dictionary* pDict = m_pPDFDoc->NewIndirect<CPDF_Dictionary>();
pDict->SetNameFor("Type", "Font");
pDict->SetNameFor("Subtype", "Type1");
pDict->SetNameFor("BaseFont", fontName);
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index 5ef47bc68e..aed5d4b2e2 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -323,8 +323,8 @@ void CPDF_StreamContentParser::AddNameParam(const FX_CHAR* name, int len) {
ContentParam& param = m_ParamBuf[GetNextParamPos()];
if (len > 32) {
param.m_Type = ContentParam::OBJECT;
- param.m_pObject = new CPDF_Name(
- m_pDocument->GetByteStringPool()->Intern(PDF_NameDecode(bsName)));
+ param.m_pObject =
+ new CPDF_Name(m_pDocument->GetByteStringPool(), PDF_NameDecode(bsName));
} else {
param.m_Type = ContentParam::NAME;
if (bsName.Find('#') == -1) {
@@ -385,8 +385,9 @@ CPDF_Object* CPDF_StreamContentParser::GetObject(uint32_t index) {
return pNumber;
}
if (param.m_Type == ContentParam::NAME) {
- CPDF_Name* pName = new CPDF_Name(m_pDocument->GetByteStringPool()->Intern(
- CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len)));
+ CPDF_Name* pName = new CPDF_Name(
+ m_pDocument->GetByteStringPool(),
+ CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len));
param.m_Type = ContentParam::OBJECT;
param.m_pObject = pName;
return pName;
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index b149f1fb98..2c2be0bd27 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -336,17 +336,17 @@ CPDF_Object* CPDF_StreamParser::ReadNextObject(bool bAllowNestedArray,
if (first_char == '/') {
CFX_ByteString name =
PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1));
- return new CPDF_Name(m_pPool ? m_pPool->Intern(name) : name);
+ return new CPDF_Name(m_pPool, name);
}
if (first_char == '(') {
CFX_ByteString str = ReadString();
- return new CPDF_String(m_pPool ? m_pPool->Intern(str) : str, false);
+ return new CPDF_String(m_pPool, str, false);
}
if (first_char == '<') {
if (m_WordSize == 1)
- return new CPDF_String(ReadHexString(), true);
+ return new CPDF_String(m_pPool, ReadHexString(), true);
CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pPool);
while (1) {
diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp
index 96ed4ae6eb..0bfcb65df9 100644
--- a/core/fpdfapi/parser/cfdf_document.cpp
+++ b/core/fpdfapi/parser/cfdf_document.cpp
@@ -24,8 +24,7 @@ CFDF_Document::~CFDF_Document() {
CFDF_Document* CFDF_Document::CreateNewDoc() {
CFDF_Document* pDoc = new CFDF_Document;
- pDoc->m_pRootDict =
- pDoc->NewIndirect<CPDF_Dictionary>(pDoc->GetByteStringPool());
+ pDoc->m_pRootDict = pDoc->NewIndirect<CPDF_Dictionary>();
pDoc->m_pRootDict->SetFor("FDF",
new CPDF_Dictionary(pDoc->GetByteStringPool()));
return pDoc;
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp
index 3edb3bb0ef..0973cb6bc6 100644
--- a/core/fpdfapi/parser/cpdf_array.cpp
+++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -18,6 +18,9 @@
CPDF_Array::CPDF_Array() {}
+CPDF_Array::CPDF_Array(const CFX_WeakPtr<CFX_ByteStringPool>& pPool)
+ : m_pPool(pPool) {}
+
CPDF_Array::~CPDF_Array() {
// Break cycles for cyclic references.
m_ObjNum = kInvalidObjNum;
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h
index b7aec7e190..125cb4cbf8 100644
--- a/core/fpdfapi/parser/cpdf_array.h
+++ b/core/fpdfapi/parser/cpdf_array.h
@@ -9,6 +9,7 @@
#include <memory>
#include <set>
+#include <type_traits>
#include <vector>
#include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
@@ -23,6 +24,7 @@ class CPDF_Array : public CPDF_Object {
std::vector<std::unique_ptr<CPDF_Object>>::const_iterator;
CPDF_Array();
+ explicit CPDF_Array(const CFX_WeakPtr<CFX_ByteStringPool>& pPool);
~CPDF_Array() override;
// CPDF_Object:
@@ -52,18 +54,44 @@ class CPDF_Array : public CPDF_Object {
CPDF_Object* InsertAt(size_t index, std::unique_ptr<CPDF_Object> pObj);
// Creates object owned by the array, returns unowned pointer to it.
+ // We have special cases for objects that can intern strings from
+ // a ByteStringPool.
template <typename T, typename... Args>
- T* AddNew(Args... args) {
+ typename std::enable_if<!CanInternStrings<T>::value, T*>::type AddNew(
+ Args... args) {
return static_cast<T*>(Add(pdfium::MakeUnique<T>(args...)));
}
template <typename T, typename... Args>
- T* SetNewAt(size_t index, Args... args) {
+ typename std::enable_if<CanInternStrings<T>::value, T*>::type AddNew(
+ Args... args) {
+ return static_cast<T*>(Add(pdfium::MakeUnique<T>(m_pPool, args...)));
+ }
+ template <typename T, typename... Args>
+ typename std::enable_if<!CanInternStrings<T>::value, T*>::type SetNewAt(
+ size_t index,
+ Args... args) {
return static_cast<T*>(SetAt(index, pdfium::MakeUnique<T>(args...)));
}
template <typename T, typename... Args>
- T* InsertNewAt(size_t index, Args... args) {
+ typename std::enable_if<CanInternStrings<T>::value, T*>::type SetNewAt(
+ size_t index,
+ Args... args) {
+ return static_cast<T*>(
+ SetAt(index, pdfium::MakeUnique<T>(m_pPool, args...)));
+ }
+ template <typename T, typename... Args>
+ typename std::enable_if<!CanInternStrings<T>::value, T*>::type InsertNewAt(
+ size_t index,
+ Args... args) {
return static_cast<T*>(InsertAt(index, pdfium::MakeUnique<T>(args...)));
}
+ template <typename T, typename... Args>
+ typename std::enable_if<CanInternStrings<T>::value, T*>::type InsertNewAt(
+ size_t index,
+ Args... args) {
+ return static_cast<T*>(
+ InsertAt(index, pdfium::MakeUnique<T>(m_pPool, args...)));
+ }
void RemoveAt(size_t index, size_t nCount = 1);
void ConvertToIndirectObjectAt(size_t index, CPDF_IndirectObjectHolder* pDoc);
@@ -77,6 +105,7 @@ class CPDF_Array : public CPDF_Object {
std::set<const CPDF_Object*>* pVisited) const override;
std::vector<std::unique_ptr<CPDF_Object>> m_Objects;
+ CFX_WeakPtr<CFX_ByteStringPool> m_pPool;
};
inline CPDF_Array* ToArray(CPDF_Object* obj) {
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index f28507e2e4..3621dbc1b7 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -238,12 +238,12 @@ void CPDF_Dictionary::SetIntegerFor(const CFX_ByteString& key, int i) {
void CPDF_Dictionary::SetNameFor(const CFX_ByteString& key,
const CFX_ByteString& name) {
- SetFor(key, new CPDF_Name(MaybeIntern(name)));
+ SetFor(key, new CPDF_Name(GetByteStringPool(), name));
}
void CPDF_Dictionary::SetStringFor(const CFX_ByteString& key,
const CFX_ByteString& str) {
- SetFor(key, new CPDF_String(MaybeIntern(str), false));
+ SetFor(key, new CPDF_String(GetByteStringPool(), str, false));
}
void CPDF_Dictionary::SetReferenceFor(const CFX_ByteString& key,
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index 9d1db26e30..c7f99fa6ef 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -647,19 +647,19 @@ CPDF_Image* CPDF_Document::LoadImageFromPageData(uint32_t dwStreamObjNum) {
void CPDF_Document::CreateNewDoc() {
ASSERT(!m_pRootDict && !m_pInfoDict);
- m_pRootDict = NewIndirect<CPDF_Dictionary>(GetByteStringPool());
+ m_pRootDict = NewIndirect<CPDF_Dictionary>();
m_pRootDict->SetNameFor("Type", "Catalog");
- CPDF_Dictionary* pPages = NewIndirect<CPDF_Dictionary>(GetByteStringPool());
+ CPDF_Dictionary* pPages = NewIndirect<CPDF_Dictionary>();
pPages->SetNameFor("Type", "Pages");
pPages->SetNumberFor("Count", 0);
pPages->SetFor("Kids", new CPDF_Array);
m_pRootDict->SetReferenceFor("Pages", this, pPages);
- m_pInfoDict = NewIndirect<CPDF_Dictionary>(GetByteStringPool());
+ m_pInfoDict = NewIndirect<CPDF_Dictionary>();
}
CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) {
- CPDF_Dictionary* pDict = NewIndirect<CPDF_Dictionary>(GetByteStringPool());
+ CPDF_Dictionary* pDict = NewIndirect<CPDF_Dictionary>();
pDict->SetNameFor("Type", "Page");
uint32_t dwObjNum = pDict->GetObjNum();
if (!InsertNewPage(iPage, pDict)) {
@@ -778,8 +778,7 @@ size_t CPDF_Document::CalculateEncodingDict(int charset,
if (i == FX_ArraySize(g_FX_CharsetUnicodes))
return i;
- CPDF_Dictionary* pEncodingDict =
- NewIndirect<CPDF_Dictionary>(GetByteStringPool());
+ CPDF_Dictionary* pEncodingDict = NewIndirect<CPDF_Dictionary>();
pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding");
CPDF_Array* pArray = new CPDF_Array;
@@ -801,8 +800,7 @@ CPDF_Dictionary* CPDF_Document::ProcessbCJK(
bool bVert,
CFX_ByteString basefont,
std::function<void(FX_WCHAR, FX_WCHAR, CPDF_Array*)> Insert) {
- CPDF_Dictionary* pFontDict =
- NewIndirect<CPDF_Dictionary>(GetByteStringPool());
+ CPDF_Dictionary* pFontDict = NewIndirect<CPDF_Dictionary>();
CFX_ByteString cmap;
CFX_ByteString ordering;
int supplement = 0;
@@ -877,8 +875,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) {
CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(),
false, false, charset == FXFONT_SYMBOL_CHARSET);
- CPDF_Dictionary* pBaseDict =
- NewIndirect<CPDF_Dictionary>(GetByteStringPool());
+ CPDF_Dictionary* pBaseDict = NewIndirect<CPDF_Dictionary>();
pBaseDict->SetNameFor("Type", "Font");
std::unique_ptr<CFX_UnicodeEncoding> pEncoding(
new CFX_UnicodeEncoding(pFont));
@@ -1008,8 +1005,7 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont,
ptm->otmrcFontBox.right, ptm->otmrcFontBox.top};
FX_Free(tm_buf);
basefont.Replace(" ", "");
- CPDF_Dictionary* pBaseDict =
- NewIndirect<CPDF_Dictionary>(GetByteStringPool());
+ CPDF_Dictionary* pBaseDict = NewIndirect<CPDF_Dictionary>();
pBaseDict->SetNameFor("Type", "Font");
CPDF_Dictionary* pFontDict = pBaseDict;
if (!bCJK) {
diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder.h b/core/fpdfapi/parser/cpdf_indirect_object_holder.h
index 375010de93..a78e6663b3 100644
--- a/core/fpdfapi/parser/cpdf_indirect_object_holder.h
+++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.h
@@ -9,14 +9,14 @@
#include <map>
#include <memory>
+#include <type_traits>
+#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fxcrt/cfx_string_pool_template.h"
#include "core/fxcrt/cfx_weak_ptr.h"
#include "core/fxcrt/fx_system.h"
#include "third_party/base/ptr_util.h"
-class CPDF_Object;
-
class CPDF_IndirectObjectHolder {
public:
using const_iterator =
@@ -30,11 +30,19 @@ class CPDF_IndirectObjectHolder {
void DeleteIndirectObject(uint32_t objnum);
// Creates and adds a new object owned by the indirect object holder,
- // and returns an unowned pointer to it.
+ // and returns an unowned pointer to it. We have a special case to
+ // handle objects that can intern strings from our ByteStringPool.
template <typename T, typename... Args>
- T* NewIndirect(Args... args) {
+ typename std::enable_if<!CanInternStrings<T>::value, T*>::type NewIndirect(
+ Args... args) {
return static_cast<T*>(AddIndirectObject(pdfium::MakeUnique<T>(args...)));
}
+ template <typename T, typename... Args>
+ typename std::enable_if<CanInternStrings<T>::value, T*>::type NewIndirect(
+ Args... args) {
+ return static_cast<T*>(
+ AddIndirectObject(pdfium::MakeUnique<T>(m_pByteStringPool, args...)));
+ }
// Takes ownership of |pObj|, returns unowned pointer to it.
CPDF_Object* AddIndirectObject(std::unique_ptr<CPDF_Object> pObj);
diff --git a/core/fpdfapi/parser/cpdf_name.cpp b/core/fpdfapi/parser/cpdf_name.cpp
index bb46425117..5be64d39d5 100644
--- a/core/fpdfapi/parser/cpdf_name.cpp
+++ b/core/fpdfapi/parser/cpdf_name.cpp
@@ -9,7 +9,12 @@
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "third_party/base/ptr_util.h"
-CPDF_Name::CPDF_Name(const CFX_ByteString& str) : m_Name(str) {}
+CPDF_Name::CPDF_Name(CFX_WeakPtr<CFX_ByteStringPool> pPool,
+ const CFX_ByteString& str)
+ : m_Name(str) {
+ if (pPool)
+ m_Name = pPool->Intern(m_Name);
+}
CPDF_Name::~CPDF_Name() {}
@@ -18,7 +23,7 @@ CPDF_Object::Type CPDF_Name::GetType() const {
}
std::unique_ptr<CPDF_Object> CPDF_Name::Clone() const {
- return pdfium::MakeUnique<CPDF_Name>(m_Name);
+ return pdfium::MakeUnique<CPDF_Name>(nullptr, m_Name);
}
CFX_ByteString CPDF_Name::GetString() const {
diff --git a/core/fpdfapi/parser/cpdf_name.h b/core/fpdfapi/parser/cpdf_name.h
index ee50595ed9..6aac24ed88 100644
--- a/core/fpdfapi/parser/cpdf_name.h
+++ b/core/fpdfapi/parser/cpdf_name.h
@@ -8,10 +8,12 @@
#define CORE_FPDFAPI_PARSER_CPDF_NAME_H_
#include "core/fpdfapi/parser/cpdf_object.h"
+#include "core/fxcrt/cfx_string_pool_template.h"
+#include "core/fxcrt/cfx_weak_ptr.h"
class CPDF_Name : public CPDF_Object {
public:
- explicit CPDF_Name(const CFX_ByteString& str);
+ CPDF_Name(CFX_WeakPtr<CFX_ByteStringPool> pPool, const CFX_ByteString& str);
~CPDF_Name() override;
// CPDF_Object:
diff --git a/core/fpdfapi/parser/cpdf_object.h b/core/fpdfapi/parser/cpdf_object.h
index c24b40a789..9c41e9de7b 100644
--- a/core/fpdfapi/parser/cpdf_object.h
+++ b/core/fpdfapi/parser/cpdf_object.h
@@ -9,6 +9,7 @@
#include <memory>
#include <set>
+#include <type_traits>
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/fx_system.h"
@@ -117,4 +118,12 @@ class CPDF_Object {
CPDF_Object(const CPDF_Object& src) {}
};
+template <typename T>
+struct CanInternStrings {
+ static const bool value = std::is_same<T, CPDF_Array>::value ||
+ std::is_same<T, CPDF_Dictionary>::value ||
+ std::is_same<T, CPDF_Name>::value ||
+ std::is_same<T, CPDF_String>::value;
+};
+
#endif // CORE_FPDFAPI_PARSER_CPDF_OBJECT_H_
diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp
index c341284602..2de6256912 100644
--- a/core/fpdfapi/parser/cpdf_object_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp
@@ -56,7 +56,7 @@ class PDFObjectsTest : public testing::Test {
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");
+ CPDF_Name* name_obj = new CPDF_Name(nullptr, "space");
// Array object.
m_ArrayObj = new CPDF_Array;
m_ArrayObj->InsertNewAt<CPDF_Number>(0, 8902);
@@ -620,12 +620,12 @@ TEST(PDFArrayTest, GetTypeAt) {
arr_val->AddNew<CPDF_Number>(2);
CPDF_Dictionary* dict_val = arr->InsertNewAt<CPDF_Dictionary>(12);
- dict_val->SetFor("key1", new CPDF_String("Linda", false));
- dict_val->SetFor("key2", new CPDF_String("Zoe", false));
+ dict_val->SetFor("key1", new CPDF_String(nullptr, "Linda", false));
+ dict_val->SetFor("key2", new CPDF_String(nullptr, "Zoe", false));
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));
+ stream_dict->SetFor("key1", new CPDF_String(nullptr, "John", false));
+ stream_dict->SetFor("key2", new CPDF_String(nullptr, "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.
@@ -710,8 +710,9 @@ TEST(PDFArrayTest, AddReferenceAndGetObjectAt) {
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_String* str_obj =
+ new CPDF_String(nullptr, "Adsfdsf 343434 %&&*\n", false);
+ CPDF_Name* name_obj = new CPDF_Name(nullptr, "Title:");
CPDF_Null* null_obj = new CPDF_Null();
CPDF_Object* indirect_objs[] = {boolean_obj, int_obj, float_obj,
str_obj, name_obj, null_obj};
diff --git a/core/fpdfapi/parser/cpdf_string.cpp b/core/fpdfapi/parser/cpdf_string.cpp
index 2116c200fe..fd4ff04ff7 100644
--- a/core/fpdfapi/parser/cpdf_string.cpp
+++ b/core/fpdfapi/parser/cpdf_string.cpp
@@ -11,8 +11,13 @@
CPDF_String::CPDF_String() : m_bHex(false) {}
-CPDF_String::CPDF_String(const CFX_ByteString& str, bool bHex)
- : m_String(str), m_bHex(bHex) {}
+CPDF_String::CPDF_String(CFX_WeakPtr<CFX_ByteStringPool> pPool,
+ const CFX_ByteString& str,
+ bool bHex)
+ : m_String(str), m_bHex(bHex) {
+ if (pPool)
+ m_String = pPool->Intern(m_String);
+}
CPDF_String::CPDF_String(const CFX_WideString& str) : m_bHex(false) {
m_String = PDF_EncodeText(str);
@@ -25,7 +30,10 @@ CPDF_Object::Type CPDF_String::GetType() const {
}
std::unique_ptr<CPDF_Object> CPDF_String::Clone() const {
- return pdfium::MakeUnique<CPDF_String>(m_String, m_bHex);
+ auto pRet = pdfium::MakeUnique<CPDF_String>();
+ pRet->m_String = m_String;
+ pRet->m_bHex = m_bHex;
+ return std::move(pRet);
}
CFX_ByteString CPDF_String::GetString() const {
diff --git a/core/fpdfapi/parser/cpdf_string.h b/core/fpdfapi/parser/cpdf_string.h
index 1e73e8699f..616e3b593d 100644
--- a/core/fpdfapi/parser/cpdf_string.h
+++ b/core/fpdfapi/parser/cpdf_string.h
@@ -8,13 +8,17 @@
#define CORE_FPDFAPI_PARSER_CPDF_STRING_H_
#include "core/fpdfapi/parser/cpdf_object.h"
+#include "core/fxcrt/cfx_string_pool_template.h"
+#include "core/fxcrt/cfx_weak_ptr.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, bool bHex);
+ CPDF_String(CFX_WeakPtr<CFX_ByteStringPool> pPool,
+ const CFX_ByteString& str,
+ bool bHex);
explicit CPDF_String(const CFX_WideString& str);
~CPDF_String() override;
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index 6a3db60286..6a38ce8c45 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
@@ -402,13 +402,13 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObject(
CFX_ByteString str = ReadString();
if (m_pCryptoHandler && bDecrypt)
m_pCryptoHandler->Decrypt(objnum, gennum, str);
- return pdfium::MakeUnique<CPDF_String>(MaybeIntern(str), false);
+ return pdfium::MakeUnique<CPDF_String>(m_pPool, str, false);
}
if (word == "<") {
CFX_ByteString str = ReadHexString();
if (m_pCryptoHandler && bDecrypt)
m_pCryptoHandler->Decrypt(objnum, gennum, str);
- return pdfium::MakeUnique<CPDF_String>(MaybeIntern(str), true);
+ return pdfium::MakeUnique<CPDF_String>(m_pPool, str, true);
}
if (word == "[") {
std::unique_ptr<CPDF_Array> pArray = pdfium::MakeUnique<CPDF_Array>();
@@ -419,8 +419,9 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObject(
return std::move(pArray);
}
if (word[0] == '/') {
- return pdfium::MakeUnique<CPDF_Name>(MaybeIntern(
- PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))));
+ return pdfium::MakeUnique<CPDF_Name>(
+ m_pPool,
+ PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
}
if (word == "<<") {
int32_t nKeys = 0;
@@ -522,13 +523,13 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectForStrict(
CFX_ByteString str = ReadString();
if (m_pCryptoHandler)
m_pCryptoHandler->Decrypt(objnum, gennum, str);
- return pdfium::MakeUnique<CPDF_String>(MaybeIntern(str), false);
+ return pdfium::MakeUnique<CPDF_String>(m_pPool, str, false);
}
if (word == "<") {
CFX_ByteString str = ReadHexString();
if (m_pCryptoHandler)
m_pCryptoHandler->Decrypt(objnum, gennum, str);
- return pdfium::MakeUnique<CPDF_String>(MaybeIntern(str), true);
+ return pdfium::MakeUnique<CPDF_String>(m_pPool, str, true);
}
if (word == "[") {
std::unique_ptr<CPDF_Array> pArray = pdfium::MakeUnique<CPDF_Array>();
@@ -539,8 +540,9 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectForStrict(
return m_WordBuffer[0] == ']' ? std::move(pArray) : nullptr;
}
if (word[0] == '/') {
- return pdfium::MakeUnique<CPDF_Name>(MaybeIntern(
- PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))));
+ return pdfium::MakeUnique<CPDF_Name>(
+ m_pPool,
+ PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
}
if (word == "<<") {
std::unique_ptr<CPDF_Dictionary> pDict =
@@ -916,7 +918,3 @@ 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/parser/cpdf_syntax_parser.h b/core/fpdfapi/parser/cpdf_syntax_parser.h
index 29eb3e1896..094872ab70 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.h
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.h
@@ -79,7 +79,6 @@ class CPDF_SyntaxParser {
uint32_t objnum,
uint32_t gennum);
- CFX_ByteString MaybeIntern(const CFX_ByteString& str);
inline bool CheckPosition(FX_FILESIZE pos) {
return m_BufOffset >= pos ||
static_cast<FX_FILESIZE>(m_BufOffset + m_BufSize) <= pos;
diff --git a/core/fpdfdoc/cpdf_filespec_unittest.cpp b/core/fpdfdoc/cpdf_filespec_unittest.cpp
index 01989ee0bd..4da5019314 100644
--- a/core/fpdfdoc/cpdf_filespec_unittest.cpp
+++ b/core/fpdfdoc/cpdf_filespec_unittest.cpp
@@ -115,7 +115,7 @@ TEST(cpdf_filespec, GetFileName) {
}
{
// Invalid object.
- std::unique_ptr<CPDF_Object> name_obj(new CPDF_Name("test.pdf"));
+ std::unique_ptr<CPDF_Object> name_obj(new CPDF_Name(nullptr, "test.pdf"));
CPDF_FileSpec file_spec(name_obj.get());
CFX_WideString file_name;
EXPECT_FALSE(file_spec.GetFileName(&file_name));
diff --git a/core/fpdfdoc/cpdf_interform.cpp b/core/fpdfdoc/cpdf_interform.cpp
index c991598a22..f541d7087c 100644
--- a/core/fpdfdoc/cpdf_interform.cpp
+++ b/core/fpdfdoc/cpdf_interform.cpp
@@ -59,8 +59,7 @@ void InitDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument) {
return;
if (!pFormDict) {
- pFormDict =
- pDocument->NewIndirect<CPDF_Dictionary>(pDocument->GetByteStringPool());
+ pFormDict = pDocument->NewIndirect<CPDF_Dictionary>();
pDocument->GetRoot()->SetReferenceFor("AcroForm", pDocument,
pFormDict->GetObjNum());
}
diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp
index c8bba64b1e..31d2242235 100644
--- a/core/fpdfdoc/cpvt_generateap.cpp
+++ b/core/fpdfdoc/cpvt_generateap.cpp
@@ -61,7 +61,7 @@ bool GenerateWidgetAP(CPDF_Document* pDoc,
CPDF_Dictionary* pFontDict = pDRFontDict->GetDictFor(sFontName.Mid(1));
if (!pFontDict) {
- pFontDict = pDoc->NewIndirect<CPDF_Dictionary>(pDoc->GetByteStringPool());
+ pFontDict = pDoc->NewIndirect<CPDF_Dictionary>();
pFontDict->SetNameFor("Type", "Font");
pFontDict->SetNameFor("Subtype", "Type1");
pFontDict->SetNameFor("BaseFont", "Helvetica");
@@ -572,8 +572,7 @@ std::unique_ptr<CPDF_Dictionary> GenerateExtGStateDict(
std::unique_ptr<CPDF_Dictionary> GenerateResourceFontDict(
CPDF_Document* pDoc,
const CFX_ByteString& sFontDictName) {
- CPDF_Dictionary* pFontDict =
- pDoc->NewIndirect<CPDF_Dictionary>(pDoc->GetByteStringPool());
+ CPDF_Dictionary* pFontDict = pDoc->NewIndirect<CPDF_Dictionary>();
pFontDict->SetNameFor("Type", "Font");
pFontDict->SetNameFor("Subtype", "Type1");
pFontDict->SetNameFor("BaseFont", "Helvetica");
diff --git a/core/fxcrt/cfx_weak_ptr.h b/core/fxcrt/cfx_weak_ptr.h
index 9ac1475884..f679696992 100644
--- a/core/fxcrt/cfx_weak_ptr.h
+++ b/core/fxcrt/cfx_weak_ptr.h
@@ -7,6 +7,7 @@
#ifndef CORE_FXCRT_CFX_WEAK_PTR_H_
#define CORE_FXCRT_CFX_WEAK_PTR_H_
+#include <cstddef>
#include <memory>
#include "core/fxcrt/cfx_retain_ptr.h"
@@ -21,6 +22,9 @@ class CFX_WeakPtr {
CFX_WeakPtr(std::unique_ptr<T, D> pObj)
: m_pHandle(new Handle(std::move(pObj))) {}
+ // Deliberately implicit to allow passing nullptr.
+ CFX_WeakPtr(std::nullptr_t arg) {}
+
explicit operator bool() const { return m_pHandle && !!m_pHandle->Get(); }
bool HasOneRef() const { return m_pHandle && m_pHandle->HasOneRef(); }
T* operator->() { return m_pHandle->Get(); }
diff --git a/fpdfsdk/formfiller/cba_fontmap.cpp b/fpdfsdk/formfiller/cba_fontmap.cpp
index 2d962ad276..fd9304befc 100644
--- a/fpdfsdk/formfiller/cba_fontmap.cpp
+++ b/fpdfsdk/formfiller/cba_fontmap.cpp
@@ -184,8 +184,7 @@ void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont,
}
CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font");
if (!pStreamResFontList) {
- pStreamResFontList = m_pDocument->NewIndirect<CPDF_Dictionary>(
- m_pDocument->GetByteStringPool());
+ pStreamResFontList = m_pDocument->NewIndirect<CPDF_Dictionary>();
pStreamResList->SetReferenceFor("Font", m_pDocument, pStreamResFontList);
}
if (!pStreamResFontList->KeyExist(sAlias)) {
diff --git a/fpdfsdk/fpdfdoc_unittest.cpp b/fpdfsdk/fpdfdoc_unittest.cpp
index 50837d52e3..d049b4e757 100644
--- a/fpdfsdk/fpdfdoc_unittest.cpp
+++ b/fpdfsdk/fpdfdoc_unittest.cpp
@@ -129,7 +129,7 @@ TEST_F(PDFDocTest, FindBookmark) {
bookmarks[2].obj->SetFor(
"Prev", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
- bookmarks[0].obj->SetFor("Type", new CPDF_Name("Outlines"));
+ bookmarks[0].obj->SetFor("Type", new CPDF_Name(nullptr, "Outlines"));
bookmarks[0].obj->SetFor("Count", new CPDF_Number(2));
bookmarks[0].obj->SetFor(
"First", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
@@ -172,7 +172,7 @@ TEST_F(PDFDocTest, FindBookmark) {
bookmarks[2].obj->SetFor(
"First", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
- bookmarks[0].obj->SetFor("Type", new CPDF_Name("Outlines"));
+ bookmarks[0].obj->SetFor("Type", new CPDF_Name(nullptr, "Outlines"));
bookmarks[0].obj->SetFor("Count", new CPDF_Number(2));
bookmarks[0].obj->SetFor(
"First", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
@@ -213,7 +213,7 @@ TEST_F(PDFDocTest, FindBookmark) {
bookmarks[3].obj->SetFor(
"Next", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
- bookmarks[0].obj->SetFor("Type", new CPDF_Name("Outlines"));
+ bookmarks[0].obj->SetFor("Type", new CPDF_Name(nullptr, "Outlines"));
bookmarks[0].obj->SetFor("Count", new CPDF_Number(2));
bookmarks[0].obj->SetFor(
"First", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp
index 9dc8ae9099..847adac7ec 100644
--- a/fpdfsdk/fpdfeditpage.cpp
+++ b/fpdfsdk/fpdfeditpage.cpp
@@ -83,8 +83,10 @@ DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument() {
CPDF_Dictionary* pInfoDict = nullptr;
pInfoDict = pDoc->GetInfo();
if (pInfoDict) {
- if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
- pInfoDict->SetFor("CreationDate", new CPDF_String(DateStr, false));
+ if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) {
+ pInfoDict->SetFor("CreationDate",
+ new CPDF_String(nullptr, DateStr, false));
+ }
pInfoDict->SetFor("Creator", new CPDF_String(L"PDFium"));
}
diff --git a/fpdfsdk/fpdfppo.cpp b/fpdfsdk/fpdfppo.cpp
index ec3312b121..915de1ad07 100644
--- a/fpdfsdk/fpdfppo.cpp
+++ b/fpdfsdk/fpdfppo.cpp
@@ -160,24 +160,24 @@ bool CPDF_PageOrganizer::PDFDocInit() {
CFX_ByteString producerstr;
producerstr.Format("PDFium");
- pDocInfoDict->SetFor("Producer", new CPDF_String(producerstr, false));
+ pDocInfoDict->SetFor("Producer",
+ new CPDF_String(nullptr, producerstr, false));
CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", "");
if (cbRootType.IsEmpty())
- pNewRoot->SetFor("Type", new CPDF_Name("Catalog"));
+ pNewRoot->SetFor("Type", new CPDF_Name(nullptr, "Catalog"));
CPDF_Object* pElement = pNewRoot->GetObjectFor("Pages");
CPDF_Dictionary* pNewPages =
pElement ? ToDictionary(pElement->GetDirect()) : nullptr;
if (!pNewPages) {
- pNewPages = m_pDestPDFDoc->NewIndirect<CPDF_Dictionary>(
- m_pDestPDFDoc->GetByteStringPool());
+ pNewPages = m_pDestPDFDoc->NewIndirect<CPDF_Dictionary>();
pNewRoot->SetReferenceFor("Pages", m_pDestPDFDoc, pNewPages);
}
CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", "");
if (cbPageType.IsEmpty())
- pNewPages->SetFor("Type", new CPDF_Name("Pages"));
+ pNewPages->SetFor("Type", new CPDF_Name(nullptr, "Pages"));
if (!pNewPages->GetArrayFor("Kids")) {
pNewPages->SetIntegerFor("Count", 0);