From 86b4f67d40c351ea8e67ba7b7dcc9d8dd7ad371e Mon Sep 17 00:00:00 2001 From: Henrique Nakashima Date: Thu, 5 Jul 2018 15:39:59 +0000 Subject: Replace SharedCopyOnWrite with RetainPtr A RetainPtr is already used inside SharedCopyOnWrite, and the API that CPDF_ContentMark offers is not intuitive. AddMark() and RemoveLastMark() currently copy the MarkData. The new API does not perform these copies, but rather leaves it to the client code. This is the first step to make CPDF_ContentMarkItems modifiable. As long as they are inside a SharedCopyOnWrite, they cannot be changed. Bug: pdfium:1037 Change-Id: I0cd6334b0b8db62070b4412f1d6d1c88bce9891f Reviewed-on: https://pdfium-review.googlesource.com/37132 Reviewed-by: Ryan Harrison Commit-Queue: Henrique Nakashima --- core/fpdfapi/page/cpdf_contentmark.cpp | 33 ++++++++++++++++++-------- core/fpdfapi/page/cpdf_contentmark.h | 7 +++--- core/fpdfapi/page/cpdf_streamcontentparser.cpp | 18 +++++++++----- core/fpdfapi/page/cpdf_streamcontentparser.h | 2 +- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/core/fpdfapi/page/cpdf_contentmark.cpp b/core/fpdfapi/page/cpdf_contentmark.cpp index deddf3cc3e..77c29a53d7 100644 --- a/core/fpdfapi/page/cpdf_contentmark.cpp +++ b/core/fpdfapi/page/cpdf_contentmark.cpp @@ -12,35 +12,48 @@ CPDF_ContentMark::CPDF_ContentMark() {} -CPDF_ContentMark::CPDF_ContentMark(const CPDF_ContentMark& that) - : m_Ref(that.m_Ref) {} - CPDF_ContentMark::~CPDF_ContentMark() {} +std::unique_ptr CPDF_ContentMark::Clone() { + auto result = pdfium::MakeUnique(); + if (m_Ref) + result->m_Ref.Reset(new MarkData(*m_Ref)); + + return result; +} + size_t CPDF_ContentMark::CountItems() const { - return m_Ref.GetObject()->CountItems(); + return m_Ref->CountItems(); } const CPDF_ContentMarkItem& CPDF_ContentMark::GetItem(size_t i) const { ASSERT(i < CountItems()); - return m_Ref.GetObject()->GetItem(i); + return m_Ref->GetItem(i); } int CPDF_ContentMark::GetMarkedContentID() const { - const MarkData* pData = m_Ref.GetObject(); - return pData ? pData->GetMarkedContentID() : -1; + if (!m_Ref) + return -1; + + return m_Ref->GetMarkedContentID(); } void CPDF_ContentMark::AddMark(ByteString name, const CPDF_Dictionary* pDict, bool bDirect) { - m_Ref.GetPrivateCopy()->AddMark(std::move(name), pDict, bDirect); + if (!m_Ref) + m_Ref.Reset(new MarkData()); + + m_Ref->AddMark(std::move(name), pDict, bDirect); } void CPDF_ContentMark::DeleteLastMark() { - m_Ref.GetPrivateCopy()->DeleteLastMark(); + if (!m_Ref) + return; + + m_Ref->DeleteLastMark(); if (CountItems() == 0) - m_Ref.SetNull(); + m_Ref.Reset(); } CPDF_ContentMark::MarkData::MarkData() {} diff --git a/core/fpdfapi/page/cpdf_contentmark.h b/core/fpdfapi/page/cpdf_contentmark.h index 494c20630b..241a0ffbf3 100644 --- a/core/fpdfapi/page/cpdf_contentmark.h +++ b/core/fpdfapi/page/cpdf_contentmark.h @@ -7,20 +7,21 @@ #ifndef CORE_FPDFAPI_PAGE_CPDF_CONTENTMARK_H_ #define CORE_FPDFAPI_PAGE_CPDF_CONTENTMARK_H_ +#include #include #include "core/fpdfapi/page/cpdf_contentmarkitem.h" #include "core/fxcrt/fx_system.h" -#include "core/fxcrt/shared_copy_on_write.h" +#include "core/fxcrt/retain_ptr.h" class CPDF_Dictionary; class CPDF_ContentMark { public: CPDF_ContentMark(); - CPDF_ContentMark(const CPDF_ContentMark& that); ~CPDF_ContentMark(); + std::unique_ptr Clone(); int GetMarkedContentID() const; size_t CountItems() const; const CPDF_ContentMarkItem& GetItem(size_t i) const; @@ -50,7 +51,7 @@ class CPDF_ContentMark { std::vector m_Marks; }; - SharedCopyOnWrite m_Ref; + RetainPtr m_Ref; }; #endif // CORE_FPDFAPI_PAGE_CPDF_CONTENTMARK_H_ diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp index 0a03ed1949..b2ac553191 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp +++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp @@ -258,6 +258,7 @@ CPDF_StreamContentParser::CPDF_StreamContentParser( m_ParamStartPos(0), m_ParamCount(0), m_pCurStates(pdfium::MakeUnique()), + m_pCurContentMark(pdfium::MakeUnique()), m_DefFontSize(0), m_PathStartX(0.0f), m_PathStartY(0.0f), @@ -434,7 +435,7 @@ void CPDF_StreamContentParser::SetGraphicStates(CPDF_PageObject* pObj, bool bGraph) { pObj->m_GeneralState = m_pCurStates->m_GeneralState; pObj->m_ClipPath = m_pCurStates->m_ClipPath; - pObj->m_ContentMark = m_CurContentMark; + pObj->m_ContentMark = *m_pCurContentMark; if (bColor) { pObj->m_ColorState = m_pCurStates->m_ColorState; } @@ -606,8 +607,10 @@ void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary() { return; bDirect = false; } - if (const CPDF_Dictionary* pDict = pProperty->AsDictionary()) - m_CurContentMark.AddMark(std::move(tag), pDict, bDirect); + if (const CPDF_Dictionary* pDict = pProperty->AsDictionary()) { + m_pCurContentMark = m_pCurContentMark->Clone(); + m_pCurContentMark->AddMark(std::move(tag), pDict, bDirect); + } } void CPDF_StreamContentParser::Handle_BeginImage() { @@ -671,7 +674,8 @@ void CPDF_StreamContentParser::Handle_BeginImage() { } void CPDF_StreamContentParser::Handle_BeginMarkedContent() { - m_CurContentMark.AddMark(GetString(0), nullptr, false); + m_pCurContentMark = m_pCurContentMark->Clone(); + m_pCurContentMark->AddMark(GetString(0), nullptr, false); } void CPDF_StreamContentParser::Handle_BeginText() { @@ -864,8 +868,10 @@ void CPDF_StreamContentParser::Handle_MarkPlace_Dictionary() {} void CPDF_StreamContentParser::Handle_EndImage() {} void CPDF_StreamContentParser::Handle_EndMarkedContent() { - if (m_CurContentMark.HasRef()) - m_CurContentMark.DeleteLastMark(); + if (m_pCurContentMark->HasRef()) { + m_pCurContentMark = m_pCurContentMark->Clone(); + m_pCurContentMark->DeleteLastMark(); + } } void CPDF_StreamContentParser::Handle_EndText() { diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.h b/core/fpdfapi/page/cpdf_streamcontentparser.h index e972118861..ae0a7f39af 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.h +++ b/core/fpdfapi/page/cpdf_streamcontentparser.h @@ -219,7 +219,7 @@ class CPDF_StreamContentParser { uint32_t m_ParamCount; UnownedPtr m_pSyntax; std::unique_ptr m_pCurStates; - CPDF_ContentMark m_CurContentMark; + std::unique_ptr m_pCurContentMark; std::vector> m_ClipTextList; UnownedPtr m_pLastTextObject; float m_DefFontSize; -- cgit v1.2.3