From 3962d80bde19074227c34f4615b0446f4975a098 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Tue, 20 Jun 2017 08:56:29 -0400 Subject: Cleanup tiling and shading patterns in correct order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a Shading is created we have both a ShadingPattern and a ShadingObject. The ShadingPattern is a ref-counted object that is stored in the CPDF_DocPageData. The ShadingObject, when we have a tiling pattern parent, is stored in the CPDF_Form of the tiling pattern. Currently during destruction it is possible for the ShadingPattern to get cleaned up before the ShadingObject which causes the UnownedPtr probe to fire. This CL loops over all patterns and for each Tiling pattern forces the CPDF_Form to get cleared. This then removes the ShadingObject before we remove the ShadingPattern. Bug: chromium:728992 Change-Id: Ife65607aa97f69440b03028981b5575b1e297093 Reviewed-on: https://pdfium-review.googlesource.com/6651 Commit-Queue: dsinclair Reviewed-by: Lei Zhang Reviewed-by: Nicolás Peña --- core/fpdfapi/page/cpdf_docpagedata.cpp | 19 ++++++++++++++++--- core/fpdfapi/page/cpdf_shadingobject.cpp | 1 - 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp index 4438006ab3..71143d0b6c 100644 --- a/core/fpdfapi/page/cpdf_docpagedata.cpp +++ b/core/fpdfapi/page/cpdf_docpagedata.cpp @@ -52,11 +52,26 @@ CPDF_DocPageData::~CPDF_DocPageData() { void CPDF_DocPageData::Clear(bool bForceRelease) { m_bForceClear = bForceRelease; + // This is needed because if |bForceRelease| is true we will destroy any + // pattern we see regardless of the ref-count. The tiling pattern owns a + // Form object which owns a ShadingObject. The ShadingObject has an unowned + // pointer to a ShadingPattern. The ShadingPattern is owned by the + // DocPageData. So, we loop through and clear any tiling patterns before we + // do the same for any shading patterns, otherwise we may free the + // ShadingPattern before the ShadingObject and trigger an unowned pointer + // probe warning. for (auto& it : m_PatternMap) { CPDF_CountedPattern* ptData = it.second; - if (!ptData->get()) + if (!ptData->get() || !ptData->get()->AsTilingPattern()) continue; + if (bForceRelease || ptData->use_count() < 2) + ptData->clear(); + } + for (auto& it : m_PatternMap) { + CPDF_CountedPattern* ptData = it.second; + if (!ptData->get()) + continue; if (bForceRelease || ptData->use_count() < 2) ptData->clear(); } @@ -65,7 +80,6 @@ void CPDF_DocPageData::Clear(bool bForceRelease) { CPDF_CountedFont* fontData = it.second; if (!fontData->get()) continue; - if (bForceRelease || fontData->use_count() < 2) { fontData->clear(); } @@ -75,7 +89,6 @@ void CPDF_DocPageData::Clear(bool bForceRelease) { CPDF_CountedColorSpace* csData = it.second; if (!csData->get()) continue; - if (bForceRelease || csData->use_count() < 2) { csData->get()->Release(); csData->reset(nullptr); diff --git a/core/fpdfapi/page/cpdf_shadingobject.cpp b/core/fpdfapi/page/cpdf_shadingobject.cpp index 5454380cae..8a61161f17 100644 --- a/core/fpdfapi/page/cpdf_shadingobject.cpp +++ b/core/fpdfapi/page/cpdf_shadingobject.cpp @@ -6,7 +6,6 @@ #include "core/fpdfapi/page/cpdf_shadingobject.h" -#include "core/fpdfapi/page/cpdf_docpagedata.h" #include "core/fpdfapi/page/cpdf_shadingpattern.h" #include "core/fpdfapi/parser/cpdf_document.h" -- cgit v1.2.3