Chromium Code Reviews| Index: core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp |
| diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp |
| index ad1ffaf6873a95216727a6817260ab160fc15d46..c64a835d65a7d54458ed6b5a19ed5c585c484ac9 100644 |
| --- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp |
| +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp |
| @@ -59,8 +59,9 @@ void CPDF_PageContentGenerator::GenerateContent() { |
| } |
| CFX_ByteString CPDF_PageContentGenerator::RealizeResource( |
| - CPDF_Object* pResourceObj, |
| + uint32_t dwResourceObjNum, |
| const CFX_ByteString& bsType) { |
| + ASSERT(dwResourceObjNum); |
| if (!m_pPage->m_pResources) { |
| m_pPage->m_pResources = |
| new CPDF_Dictionary(m_pDocument->GetByteStringPool()); |
| @@ -82,8 +83,7 @@ CFX_ByteString CPDF_PageContentGenerator::RealizeResource( |
| } |
| idnum++; |
| } |
| - pResList->SetReferenceFor(name, m_pDocument, |
| - m_pDocument->AddIndirectObject(pResourceObj)); |
| + pResList->SetReferenceFor(name, m_pDocument, dwResourceObjNum); |
| return name; |
| } |
| @@ -94,16 +94,23 @@ void CPDF_PageContentGenerator::ProcessImage(CFX_ByteTextBuf& buf, |
| return; |
| } |
| buf << "q " << pImageObj->m_Matrix << " cm "; |
| + |
| CPDF_Image* pImage = pImageObj->GetImage(); |
| - if (!pImage->IsInline()) { |
| - CPDF_Stream* pStream = pImage->GetStream(); |
| - uint32_t dwSavedObjNum = pStream->GetObjNum(); |
| - CFX_ByteString name = RealizeResource(pStream, "XObject"); |
| - if (dwSavedObjNum == 0) { |
| - pImageObj->SetUnownedImage(m_pDocument->GetPageData()->GetImage(pStream)); |
| - } |
| - buf << "/" << PDF_NameEncode(name) << " Do Q\n"; |
| + if (pImage->IsInline()) |
| + return; |
| + |
| + CPDF_Stream* pStream = pImage->GetStream(); |
| + bool bWasInline = pStream->IsInline(); |
| + if (bWasInline) { |
| + pStream = ToStream(pStream->Clone().release()); |
|
Tom Sepez
2016/11/10 21:15:26
Note: this is the clone that avoids the UAF. The
|
| + m_pDocument->AddIndirectObject(pStream); |
| } |
| + |
| + CFX_ByteString name = RealizeResource(pStream->GetObjNum(), "XObject"); |
| + if (bWasInline) |
| + pImageObj->SetUnownedImage(m_pDocument->GetPageData()->GetImage(pStream)); |
| + |
| + buf << "/" << PDF_NameEncode(name) << " Do Q\n"; |
| } |
| void CPDF_PageContentGenerator::ProcessForm(CFX_ByteTextBuf& buf, |
| @@ -113,20 +120,22 @@ void CPDF_PageContentGenerator::ProcessForm(CFX_ByteTextBuf& buf, |
| if (!data || !size) |
| return; |
| + buf << "q " << matrix << " cm "; |
| + |
| + CFX_FloatRect bbox = m_pPage->GetPageBBox(); |
| + matrix.TransformRect(bbox); |
| + |
| CPDF_Dictionary* pFormDict = |
| new CPDF_Dictionary(m_pDocument->GetByteStringPool()); |
| pFormDict->SetNameFor("Type", "XObject"); |
| pFormDict->SetNameFor("Subtype", "Form"); |
| - |
| - CFX_FloatRect bbox = m_pPage->GetPageBBox(); |
| - matrix.TransformRect(bbox); |
| pFormDict->SetRectFor("BBox", bbox); |
| CPDF_Stream* pStream = new CPDF_Stream; |
| pStream->InitStream(data, size, pFormDict); |
| - buf << "q " << matrix << " cm "; |
| - CFX_ByteString name = RealizeResource(pStream, "XObject"); |
| + CFX_ByteString name = |
| + RealizeResource(m_pDocument->AddIndirectObject(pStream), "XObject"); |
| buf << "/" << PDF_NameEncode(name) << " Do Q\n"; |
| } |