diff options
author | tsepez <tsepez@chromium.org> | 2016-11-18 16:22:41 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-11-18 16:22:41 -0800 |
commit | 0e606b5ecd6e45f74391f110cc1fe0cce0e80c64 (patch) | |
tree | 07c55fac710b191cf5d1d6595c63b90ca52e3cbb /core/fpdfapi | |
parent | 430ab8363e77c48b2c2435af4d289f85e2be1b96 (diff) | |
download | pdfium-0e606b5ecd6e45f74391f110cc1fe0cce0e80c64.tar.xz |
Make CPDF_Dictionary use unique pointers.chromium/2926
Some changes were required to match underlying ctors
as invoked by the templated methods.
Many release() calls go away, a few WrapUniques() are
introduced to avoid going deeper into other code.
Review-Url: https://codereview.chromium.org/2510223002
Diffstat (limited to 'core/fpdfapi')
24 files changed, 301 insertions, 305 deletions
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp index 80450a8025..837697273f 100644 --- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp @@ -16,6 +16,8 @@ #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_document.h" +#include "core/fpdfapi/parser/cpdf_name.h" +#include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/cpdf_stream_acc.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" @@ -54,7 +56,8 @@ void CPDF_PageContentGenerator::GenerateContent() { CPDF_Stream* pStream = m_pDocument->NewIndirect<CPDF_Stream>(); pStream->SetData(buf.GetBuffer(), buf.GetLength()); - pPageDict->SetReferenceFor("Contents", m_pDocument, pStream); + pPageDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument, + pStream->GetObjNum()); } CFX_ByteString CPDF_PageContentGenerator::RealizeResource( @@ -63,14 +66,13 @@ CFX_ByteString CPDF_PageContentGenerator::RealizeResource( ASSERT(dwResourceObjNum); if (!m_pPage->m_pResources) { m_pPage->m_pResources = m_pDocument->NewIndirect<CPDF_Dictionary>(); - m_pPage->m_pFormDict->SetReferenceFor("Resources", m_pDocument, - m_pPage->m_pResources); + m_pPage->m_pFormDict->SetNewFor<CPDF_Reference>( + "Resources", m_pDocument, m_pPage->m_pResources->GetObjNum()); } CPDF_Dictionary* pResList = m_pPage->m_pResources->GetDictFor(bsType); - if (!pResList) { - pResList = new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - m_pPage->m_pResources->SetFor(bsType, pResList); - } + if (!pResList) + pResList = m_pPage->m_pResources->SetNewFor<CPDF_Dictionary>(bsType); + CFX_ByteString name; int idnum = 1; while (1) { @@ -80,7 +82,7 @@ CFX_ByteString CPDF_PageContentGenerator::RealizeResource( } idnum++; } - pResList->SetReferenceFor(name, m_pDocument, dwResourceObjNum); + pResList->SetNewFor<CPDF_Reference>(name, m_pDocument, dwResourceObjNum); return name; } @@ -126,8 +128,8 @@ void CPDF_PageContentGenerator::ProcessForm(CFX_ByteTextBuf& buf, CPDF_Dictionary* pFormDict = new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - pFormDict->SetNameFor("Type", "XObject"); - pFormDict->SetNameFor("Subtype", "Form"); + pFormDict->SetNewFor<CPDF_Name>("Type", "XObject"); + pFormDict->SetNewFor<CPDF_Name>("Subtype", "Form"); pFormDict->SetRectFor("BBox", bbox); CPDF_Stream* pStream = m_pDocument->NewIndirect<CPDF_Stream>(); @@ -179,5 +181,6 @@ void CPDF_PageContentGenerator::TransformContent(CFX_Matrix& matrix) { } CPDF_Stream* pStream = m_pDocument->NewIndirect<CPDF_Stream>(); pStream->SetData(buf.GetBuffer(), buf.GetLength()); - m_pPage->m_pFormDict->SetReferenceFor("Contents", m_pDocument, pStream); + m_pPage->m_pFormDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument, + pStream->GetObjNum()); } diff --git a/core/fpdfapi/edit/fpdf_edit_create.cpp b/core/fpdfapi/edit/fpdf_edit_create.cpp index 360472948d..b2e31054c0 100644 --- a/core/fpdfapi/edit/fpdf_edit_create.cpp +++ b/core/fpdfapi/edit/fpdf_edit_create.cpp @@ -13,6 +13,8 @@ #include "core/fpdfapi/parser/cpdf_crypto_handler.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_document.h" +#include "core/fpdfapi/parser/cpdf_name.h" +#include "core/fpdfapi/parser/cpdf_number.h" #include "core/fpdfapi/parser/cpdf_parser.h" #include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfapi/parser/cpdf_security_handler.h" @@ -128,7 +130,7 @@ int32_t PDF_CreatorAppendObject(const CPDF_Object* pObj, const CPDF_Dictionary* p = pObj->AsDictionary(); for (const auto& it : *p) { const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second; + CPDF_Object* pValue = it.second.get(); if (pFile->AppendString("/") < 0) { return -1; } @@ -197,7 +199,7 @@ int32_t PDF_CreatorWriteTrailer(CPDF_Document* pDocument, CPDF_Dictionary* p = pParser->GetTrailer(); for (const auto& it : *p) { const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second; + CPDF_Object* pValue = it.second.get(); if (key == "Encrypt" || key == "Size" || key == "Filter" || key == "Index" || key == "Length" || key == "Prev" || key == "W" || key == "XRefStm" || key == "Type" || key == "ID") { @@ -440,8 +442,8 @@ CPDF_FlateEncoder::CPDF_FlateEncoder(CPDF_Stream* pStream, bool bFlateEncode) // TODO(thestig): Move to Init() and check return value. ::FlateEncode(m_Acc.GetData(), m_Acc.GetSize(), &m_pData, &m_dwSize); m_pDict = ToDictionary(pStream->GetDict()->Clone().release()); - m_pDict->SetIntegerFor("Length", m_dwSize); - m_pDict->SetNameFor("Filter", "FlateDecode"); + m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(m_dwSize)); + m_pDict->SetNewFor<CPDF_Name>("Filter", "FlateDecode"); m_pDict->RemoveFor("DecodeParms"); } @@ -993,7 +995,8 @@ int32_t CPDF_Creator::WriteStream(const CPDF_Object* pStream, if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") != encryptor.m_dwSize) { encoder.CloneDict(); - encoder.m_pDict->SetIntegerFor("Length", encryptor.m_dwSize); + encoder.m_pDict->SetNewFor<CPDF_Number>( + "Length", static_cast<int>(encryptor.m_dwSize)); } if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { return -1; @@ -1106,7 +1109,8 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") != encryptor.m_dwSize) { encoder.CloneDict(); - encoder.m_pDict->SetIntegerFor("Length", encryptor.m_dwSize); + encoder.m_pDict->SetNewFor<CPDF_Number>( + "Length", static_cast<int>(encryptor.m_dwSize)); } if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { return -1; @@ -1189,7 +1193,7 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, for (const auto& it : *p) { bool bSignValue = false; const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second; + CPDF_Object* pValue = it.second.get(); if (m_File.AppendString("/") < 0) { return -1; } @@ -1711,7 +1715,7 @@ int32_t CPDF_Creator::WriteDoc_Stage4(IFX_Pause* pPause) { CPDF_Dictionary* p = m_pParser->GetTrailer(); for (const auto& it : *p) { const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second; + CPDF_Object* pValue = it.second.get(); // TODO(ochang): Consolidate with similar check in // PDF_CreatorWriteTrailer. if (key == "Encrypt" || key == "Size" || key == "Filter" || diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp index c5da4ea519..c7725c3fce 100644 --- a/core/fpdfapi/font/cpdf_font.cpp +++ b/core/fpdfapi/font/cpdf_font.cpp @@ -7,6 +7,7 @@ #include "core/fpdfapi/font/cpdf_font.h" #include <memory> +#include <utility> #include <vector> #include "core/fpdfapi/cpdf_modulemgr.h" @@ -310,10 +311,10 @@ CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, return pFont; CPDF_Dictionary* pDict = new CPDF_Dictionary(pDoc->GetByteStringPool()); - pDict->SetNameFor("Type", "Font"); - pDict->SetNameFor("Subtype", "Type1"); - pDict->SetNameFor("BaseFont", fontname); - pDict->SetNameFor("Encoding", "WinAnsiEncoding"); + pDict->SetNewFor<CPDF_Name>("Type", "Font"); + pDict->SetNewFor<CPDF_Name>("Subtype", "Type1"); + pDict->SetNewFor<CPDF_Name>("BaseFont", fontname); + pDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding"); return pFontGlobals->Set(pDoc, font_id, CPDF_Font::Create(nullptr, pDict)); } diff --git a/core/fpdfapi/font/cpdf_fontencoding.cpp b/core/fpdfapi/font/cpdf_fontencoding.cpp index da607e6aa8..df21267e1d 100644 --- a/core/fpdfapi/font/cpdf_fontencoding.cpp +++ b/core/fpdfapi/font/cpdf_fontencoding.cpp @@ -6,6 +6,8 @@ #include "core/fpdfapi/font/cpdf_fontencoding.h" +#include <utility> + #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_name.h" @@ -1701,7 +1703,7 @@ CPDF_Object* CPDF_FontEncoding::Realize(CFX_WeakPtr<CFX_ByteStringPool> pPool) { } const uint16_t* pStandard = PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI); - CPDF_Array* pDiff = new CPDF_Array; + auto pDiff = pdfium::MakeUnique<CPDF_Array>(); for (int i = 0; i < 256; i++) { if (pStandard[i] == m_Unicodes[i]) continue; @@ -1711,8 +1713,8 @@ CPDF_Object* CPDF_FontEncoding::Realize(CFX_WeakPtr<CFX_ByteStringPool> pPool) { } CPDF_Dictionary* pDict = new CPDF_Dictionary(pPool); - pDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); - pDict->SetFor("Differences", pDiff); + pDict->SetNewFor<CPDF_Name>("BaseEncoding", "WinAnsiEncoding"); + pDict->SetFor("Differences", std::move(pDiff)); return pDict; } diff --git a/core/fpdfapi/page/cpdf_allstates.cpp b/core/fpdfapi/page/cpdf_allstates.cpp index 012c1349c0..f88342d7d7 100644 --- a/core/fpdfapi/page/cpdf_allstates.cpp +++ b/core/fpdfapi/page/cpdf_allstates.cpp @@ -6,6 +6,8 @@ #include "core/fpdfapi/page/cpdf_allstates.h" +#include <algorithm> + #include "core/fpdfapi/page/pageint.h" #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" @@ -52,7 +54,7 @@ void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser) { for (const auto& it : *pGS) { const CFX_ByteString& key_str = it.first; - CPDF_Object* pElement = it.second; + CPDF_Object* pElement = it.second.get(); CPDF_Object* pObject = pElement ? pElement->GetDirect() : nullptr; if (!pObject) continue; diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp index 0c023d19ff..b1675d87a7 100644 --- a/core/fpdfapi/page/cpdf_colorspace.cpp +++ b/core/fpdfapi/page/cpdf_colorspace.cpp @@ -345,7 +345,7 @@ std::unique_ptr<CPDF_ColorSpace> CPDF_ColorSpace::Load(CPDF_Document* pDoc, for (const auto& it : *pDict) { std::unique_ptr<CPDF_ColorSpace> pRet; - CPDF_Object* pValue = it.second; + CPDF_Object* pValue = it.second.get(); if (ToName(pValue)) pRet.reset(ColorspaceFromName(pValue->GetString())); if (pRet) diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp index b849bc4107..3df771070e 100644 --- a/core/fpdfapi/page/cpdf_docpagedata.cpp +++ b/core/fpdfapi/page/cpdf_docpagedata.cpp @@ -7,6 +7,7 @@ #include "core/fpdfapi/page/cpdf_docpagedata.h" #include <algorithm> +#include <memory> #include <set> #include "core/fdrm/crypto/fx_crypt.h" @@ -21,6 +22,7 @@ #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_document.h" +#include "core/fpdfapi/parser/cpdf_name.h" #include "core/fpdfapi/parser/cpdf_stream_acc.h" #include "third_party/base/stl_util.h" @@ -176,12 +178,13 @@ CPDF_Font* CPDF_DocPageData::GetStandardFont(const CFX_ByteString& fontName, } CPDF_Dictionary* pDict = m_pPDFDoc->NewIndirect<CPDF_Dictionary>(); - pDict->SetNameFor("Type", "Font"); - pDict->SetNameFor("Subtype", "Type1"); - pDict->SetNameFor("BaseFont", fontName); + pDict->SetNewFor<CPDF_Name>("Type", "Font"); + pDict->SetNewFor<CPDF_Name>("Subtype", "Type1"); + pDict->SetNewFor<CPDF_Name>("BaseFont", fontName); if (pEncoding) { - pDict->SetFor("Encoding", - pEncoding->Realize(m_pPDFDoc->GetByteStringPool())); + pDict->SetFor( + "Encoding", + pdfium::WrapUnique(pEncoding->Realize(m_pPDFDoc->GetByteStringPool()))); } std::unique_ptr<CPDF_Font> pFont = CPDF_Font::Create(m_pPDFDoc, pDict); diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp index 1c3aa89ff2..8ded34e630 100644 --- a/core/fpdfapi/page/cpdf_image.cpp +++ b/core/fpdfapi/page/cpdf_image.cpp @@ -8,6 +8,7 @@ #include <algorithm> #include <memory> +#include <utility> #include <vector> #include "core/fpdfapi/cpdf_modulemgr.h" @@ -97,10 +98,10 @@ CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, uint32_t size) { CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - pDict->SetNameFor("Type", "XObject"); - pDict->SetNameFor("Subtype", "Image"); - pDict->SetIntegerFor("Width", width); - pDict->SetIntegerFor("Height", height); + pDict->SetNewFor<CPDF_Name>("Type", "XObject"); + pDict->SetNewFor<CPDF_Name>("Subtype", "Image"); + pDict->SetNewFor<CPDF_Number>("Width", width); + pDict->SetNewFor<CPDF_Number>("Height", height); const FX_CHAR* csname = nullptr; if (num_comps == 1) { csname = "DeviceGray"; @@ -108,21 +109,18 @@ CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, uint32_t size) { csname = "DeviceRGB"; } else if (num_comps == 4) { csname = "DeviceCMYK"; - CPDF_Array* pDecode = new CPDF_Array; + CPDF_Array* pDecode = pDict->SetNewFor<CPDF_Array>("Decode"); for (int n = 0; n < 4; n++) { pDecode->AddNew<CPDF_Number>(1); pDecode->AddNew<CPDF_Number>(0); } - pDict->SetFor("Decode", pDecode); } - pDict->SetNameFor("ColorSpace", csname); - pDict->SetIntegerFor("BitsPerComponent", bits); - pDict->SetNameFor("Filter", "DCTDecode"); + pDict->SetNewFor<CPDF_Name>("ColorSpace", csname); + pDict->SetNewFor<CPDF_Number>("BitsPerComponent", bits); + pDict->SetNewFor<CPDF_Name>("Filter", "DCTDecode"); if (!color_trans) { - CPDF_Dictionary* pParms = - new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - pDict->SetFor("DecodeParms", pParms); - pParms->SetIntegerFor("ColorTransform", 0); + CPDF_Dictionary* pParms = pDict->SetNewFor<CPDF_Dictionary>("DecodeParms"); + pParms->SetNewFor<CPDF_Number>("ColorTransform", 0); } m_bIsMask = false; m_Width = width; @@ -166,10 +164,10 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - pDict->SetNameFor("Type", "XObject"); - pDict->SetNameFor("Subtype", "Image"); - pDict->SetIntegerFor("Width", BitmapWidth); - pDict->SetIntegerFor("Height", BitmapHeight); + pDict->SetNewFor<CPDF_Name>("Type", "XObject"); + pDict->SetNewFor<CPDF_Name>("Subtype", "Image"); + pDict->SetNewFor<CPDF_Number>("Width", BitmapWidth); + pDict->SetNewFor<CPDF_Number>("Height", BitmapHeight); uint8_t* dest_buf = nullptr; FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1; if (bpp == 1) { @@ -181,15 +179,14 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { ArgbDecode(pBitmap->GetPaletteArgb(1), set_a, set_r, set_g, set_b); } if (set_a == 0 || reset_a == 0) { - pDict->SetFor("ImageMask", new CPDF_Boolean(true)); + pDict->SetNewFor<CPDF_Boolean>("ImageMask", true); if (reset_a == 0) { - CPDF_Array* pArray = new CPDF_Array; + CPDF_Array* pArray = pDict->SetNewFor<CPDF_Array>("Decode"); pArray->AddNew<CPDF_Number>(1); pArray->AddNew<CPDF_Number>(0); - pDict->SetFor("Decode", pArray); } } else { - CPDF_Array* pCS = new CPDF_Array; + CPDF_Array* pCS = pDict->SetNewFor<CPDF_Array>("ColorSpace"); pCS->AddNew<CPDF_Name>("Indexed"); pCS->AddNew<CPDF_Name>("DeviceRGB"); pCS->AddNew<CPDF_Number>(1); @@ -203,9 +200,8 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { pBuf[5] = (FX_CHAR)set_b; ct.ReleaseBuffer(6); pCS->AddNew<CPDF_String>(ct, true); - pDict->SetFor("ColorSpace", pCS); } - pDict->SetIntegerFor("BitsPerComponent", 1); + pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 1); dest_pitch = (BitmapWidth + 7) / 8; if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { opType = 1; @@ -232,11 +228,12 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { pColorTable, iPalette * 3, new CPDF_Dictionary(m_pDocument->GetByteStringPool())); pCS->AddNew<CPDF_Reference>(m_pDocument, pCTS->GetObjNum()); - pDict->SetReferenceFor("ColorSpace", m_pDocument, pCS); + pDict->SetNewFor<CPDF_Reference>("ColorSpace", m_pDocument, + pCS->GetObjNum()); } else { - pDict->SetNameFor("ColorSpace", "DeviceGray"); + pDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray"); } - pDict->SetIntegerFor("BitsPerComponent", 8); + pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8); if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { dest_pitch = BitmapWidth; opType = 1; @@ -244,8 +241,8 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { opType = 0; } } else { - pDict->SetNameFor("ColorSpace", "DeviceRGB"); - pDict->SetIntegerFor("BitsPerComponent", 8); + pDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceRGB"); + pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8); if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { dest_pitch = BitmapWidth * 3; opType = 2; @@ -266,12 +263,12 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { FX_STRSIZE mask_size = 0; CPDF_Dictionary* pMaskDict = new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - pMaskDict->SetNameFor("Type", "XObject"); - pMaskDict->SetNameFor("Subtype", "Image"); - pMaskDict->SetIntegerFor("Width", maskWidth); - pMaskDict->SetIntegerFor("Height", maskHeight); - pMaskDict->SetNameFor("ColorSpace", "DeviceGray"); - pMaskDict->SetIntegerFor("BitsPerComponent", 8); + pMaskDict->SetNewFor<CPDF_Name>("Type", "XObject"); + pMaskDict->SetNewFor<CPDF_Name>("Subtype", "Image"); + pMaskDict->SetNewFor<CPDF_Number>("Width", maskWidth); + pMaskDict->SetNewFor<CPDF_Number>("Height", maskHeight); + pMaskDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray"); + pMaskDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8); if (pMaskBitmap->GetBPP() == 8 && (iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) { } else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) { @@ -283,10 +280,11 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { maskWidth); } } - pMaskDict->SetIntegerFor("Length", mask_size); - pDict->SetReferenceFor( + pMaskDict->SetNewFor<CPDF_Number>("Length", mask_size); + pDict->SetNewFor<CPDF_Reference>( "SMask", m_pDocument, - m_pDocument->NewIndirect<CPDF_Stream>(mask_buf, mask_size, pMaskDict)); + m_pDocument->NewIndirect<CPDF_Stream>(mask_buf, mask_size, pMaskDict) + ->GetObjNum()); if (bDeleteMask) delete pMaskBitmap; } diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp index aed5d4b2e2..6ddd278e27 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp +++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp @@ -30,6 +30,7 @@ #include "core/fpdfapi/parser/cpdf_document.h" #include "core/fpdfapi/parser/cpdf_name.h" #include "core/fpdfapi/parser/cpdf_number.h" +#include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "core/fxcrt/fx_safe_types.h" @@ -172,7 +173,7 @@ void ReplaceAbbr(CPDF_Object* pObj) { std::vector<AbbrReplacementOp> replacements; for (const auto& it : *pDict) { CFX_ByteString key = it.first; - CPDF_Object* value = it.second; + CPDF_Object* value = it.second.get(); CFX_ByteStringC fullname = FindFullName( InlineKeyAbbr, FX_ArraySize(InlineKeyAbbr), key.AsStringC()); if (!fullname.IsEmpty()) { @@ -203,7 +204,7 @@ void ReplaceAbbr(CPDF_Object* pObj) { if (op.is_replace_key) pDict->ReplaceKey(op.key, CFX_ByteString(op.replacement)); else - pDict->SetNameFor(op.key, CFX_ByteString(op.replacement)); + pDict->SetNewFor<CPDF_Name>(op.key, CFX_ByteString(op.replacement)); } break; } @@ -650,13 +651,13 @@ void CPDF_StreamContentParser::Handle_BeginImage() { } CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, m_pSyntax->GetWordSize() - 1); - std::unique_ptr<CPDF_Object> pObj(m_pSyntax->ReadNextObject(false, 0)); + auto pObj = pdfium::WrapUnique(m_pSyntax->ReadNextObject(false, 0)); if (!key.IsEmpty()) { uint32_t dwObjNum = pObj ? pObj->GetObjNum() : 0; if (dwObjNum) - pDict->SetReferenceFor(key, m_pDocument, dwObjNum); + pDict->SetNewFor<CPDF_Reference>(key, m_pDocument, dwObjNum); else - pDict->SetFor(key, pObj.release()); + pDict->SetFor(key, std::move(pObj)); } } ReplaceAbbr(pDict); @@ -667,14 +668,12 @@ void CPDF_StreamContentParser::Handle_BeginImage() { CFX_ByteString name = pCSObj->GetString(); if (name != "DeviceRGB" && name != "DeviceGray" && name != "DeviceCMYK") { pCSObj = FindResourceObj("ColorSpace", name); - if (pCSObj && pCSObj->IsInline()) { - pCSObj = pCSObj->Clone().release(); - pDict->SetFor("ColorSpace", pCSObj); - } + if (pCSObj && pCSObj->IsInline()) + pDict->SetFor("ColorSpace", pCSObj->Clone()); } } } - pDict->SetNameFor("Subtype", "Image"); + pDict->SetNewFor<CPDF_Name>("Subtype", "Image"); std::unique_ptr<CPDF_Stream> pStream( m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSObj)); bool bGaveDictAway = !!pStream; diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp index 2c2be0bd27..6b4a362257 100644 --- a/core/fpdfapi/page/cpdf_streamparser.cpp +++ b/core/fpdfapi/page/cpdf_streamparser.cpp @@ -8,6 +8,8 @@ #include <limits.h> +#include <utility> + #include "core/fpdfapi/cpdf_modulemgr.h" #include "core/fpdfapi/page/cpdf_docpagedata.h" #include "core/fpdfapi/parser/cpdf_array.h" @@ -230,7 +232,7 @@ CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize); m_Pos += dwStreamSize; } - pDict->SetIntegerFor("Length", (int)dwStreamSize); + pDict->SetNewFor<CPDF_Number>("Length", (int)dwStreamSize); return new CPDF_Stream(pData, dwStreamSize, pDict); } @@ -361,16 +363,13 @@ CPDF_Object* CPDF_StreamParser::ReadNextObject(bool bAllowNestedArray, CFX_ByteString key = PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); - CPDF_Object* pObj = ReadNextObject(true, 0); + auto pObj = pdfium::WrapUnique(ReadNextObject(true, 0)); if (!pObj) { delete pDict; return nullptr; } - - if (key.IsEmpty()) - delete pObj; - else - pDict->SetFor(key, pObj); + if (!key.IsEmpty()) + pDict->SetFor(key, std::move(pObj)); } return pDict; } diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp index 0bfcb65df9..546308c3a3 100644 --- a/core/fpdfapi/parser/cfdf_document.cpp +++ b/core/fpdfapi/parser/cfdf_document.cpp @@ -6,6 +6,9 @@ #include "core/fpdfapi/parser/cfdf_document.h" +#include <memory> +#include <utility> + #include "core/fpdfapi/edit/cpdf_creator.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_syntax_parser.h" @@ -25,8 +28,7 @@ CFDF_Document::~CFDF_Document() { CFDF_Document* CFDF_Document::CreateNewDoc() { CFDF_Document* pDoc = new CFDF_Document; pDoc->m_pRootDict = pDoc->NewIndirect<CPDF_Dictionary>(); - pDoc->m_pRootDict->SetFor("FDF", - new CPDF_Dictionary(pDoc->GetByteStringPool())); + pDoc->m_pRootDict->SetNewFor<CPDF_Dictionary>("FDF"); return pDoc; } diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp index 6af2da6ff0..1ac6e06a97 100644 --- a/core/fpdfapi/parser/cpdf_data_avail.cpp +++ b/core/fpdfapi/parser/cpdf_data_avail.cpp @@ -142,10 +142,8 @@ bool CPDF_DataAvail::AreObjectsAvailable(std::vector<CPDF_Object*>& obj_array, continue; for (const auto& it : *pDict) { - const CFX_ByteString& key = it.first; - CPDF_Object* value = it.second; - if (key != "Parent") - new_obj_array.push_back(value); + if (it.first != "Parent") + new_obj_array.push_back(it.second.get()); } } break; case CPDF_Object::REFERENCE: { diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp index 3621dbc1b7..40877539b5 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.cpp +++ b/core/fpdfapi/parser/cpdf_dictionary.cpp @@ -26,12 +26,12 @@ 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. + // Mark the object as deleted so that it will not be deleted again, + // and break cyclic references. m_ObjNum = kInvalidObjNum; - for (const auto& it : m_Map) { - if (it.second && it.second->GetObjNum() != kInvalidObjNum) - delete it.second; + for (auto& it : m_Map) { + if (it.second && it.second->GetObjNum() == kInvalidObjNum) + it.second.release(); } } @@ -67,10 +67,9 @@ std::unique_ptr<CPDF_Object> CPDF_Dictionary::CloneNonCyclic( pVisited->insert(this); auto pCopy = pdfium::MakeUnique<CPDF_Dictionary>(m_pPool); for (const auto& it : *this) { - CPDF_Object* value = it.second; - if (!pdfium::ContainsKey(*pVisited, value)) { + if (!pdfium::ContainsKey(*pVisited, it.second.get())) { pCopy->m_Map.insert(std::make_pair( - it.first, value->CloneNonCyclic(bDirect, pVisited).release())); + it.first, it.second->CloneNonCyclic(bDirect, pVisited))); } } return std::move(pCopy); @@ -78,7 +77,7 @@ std::unique_ptr<CPDF_Object> CPDF_Dictionary::CloneNonCyclic( CPDF_Object* CPDF_Dictionary::GetObjectFor(const CFX_ByteString& key) const { auto it = m_Map.find(key); - return it != m_Map.end() ? it->second : nullptr; + return it != m_Map.end() ? it->second.get() : nullptr; } CPDF_Object* CPDF_Dictionary::GetDirectObjectFor( @@ -173,23 +172,16 @@ bool CPDF_Dictionary::IsSignatureDict() const { return pType && pType->GetString() == "Sig"; } -void CPDF_Dictionary::SetFor(const CFX_ByteString& key, CPDF_Object* pObj) { - CHECK(!pObj || pObj->IsInline()); - auto it = m_Map.find(key); - if (it == m_Map.end()) { - if (pObj) - m_Map.insert(std::make_pair(MaybeIntern(key), pObj)); - return; +CPDF_Object* CPDF_Dictionary::SetFor(const CFX_ByteString& key, + std::unique_ptr<CPDF_Object> pObj) { + if (!pObj) { + m_Map.erase(key); + return nullptr; } - - if (it->second == pObj) - return; - delete it->second; - - if (pObj) - it->second = pObj; - else - m_Map.erase(it); + ASSERT(pObj->IsInline()); + CPDF_Object* pRet = pObj.get(); + m_Map[MaybeIntern(key)] = std::move(pObj); + return pRet; } void CPDF_Dictionary::ConvertToIndirectObjectFor( @@ -199,18 +191,12 @@ void CPDF_Dictionary::ConvertToIndirectObjectFor( if (it == m_Map.end() || it->second->IsReference()) return; - CPDF_Object* pObj = - pHolder->AddIndirectObject(pdfium::WrapUnique(it->second)); - it->second = new CPDF_Reference(pHolder, pObj->GetObjNum()); + CPDF_Object* pObj = pHolder->AddIndirectObject(std::move(it->second)); + it->second = pdfium::MakeUnique<CPDF_Reference>(pHolder, pObj->GetObjNum()); } void CPDF_Dictionary::RemoveFor(const CFX_ByteString& key) { - auto it = m_Map.find(key); - if (it == m_Map.end()) - return; - - delete it->second; - m_Map.erase(it); + m_Map.erase(key); } void CPDF_Dictionary::ReplaceKey(const CFX_ByteString& oldkey, @@ -223,70 +209,28 @@ void CPDF_Dictionary::ReplaceKey(const CFX_ByteString& oldkey, if (new_it == old_it) return; - if (new_it != m_Map.end()) { - delete new_it->second; - new_it->second = old_it->second; - } else { - m_Map.insert(std::make_pair(MaybeIntern(newkey), old_it->second)); - } + m_Map[MaybeIntern(newkey)] = std::move(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(GetByteStringPool(), name)); -} - -void CPDF_Dictionary::SetStringFor(const CFX_ByteString& key, - const CFX_ByteString& str) { - SetFor(key, new CPDF_String(GetByteStringPool(), 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::SetReferenceFor(const CFX_ByteString& key, - CPDF_IndirectObjectHolder* pDoc, - CPDF_Object* pObj) { - ASSERT(!pObj->IsInline()); - SetFor(key, new CPDF_Reference(pDoc, pObj->GetObjNum())); -} - -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; + CPDF_Array* pArray = SetNewFor<CPDF_Array>(key); pArray->AddNew<CPDF_Number>(rect.left); pArray->AddNew<CPDF_Number>(rect.bottom); pArray->AddNew<CPDF_Number>(rect.right); pArray->AddNew<CPDF_Number>(rect.top); - SetFor(key, pArray); } void CPDF_Dictionary::SetMatrixFor(const CFX_ByteString& key, const CFX_Matrix& matrix) { - CPDF_Array* pArray = new CPDF_Array; + CPDF_Array* pArray = SetNewFor<CPDF_Array>(key); pArray->AddNew<CPDF_Number>(matrix.a); pArray->AddNew<CPDF_Number>(matrix.b); pArray->AddNew<CPDF_Number>(matrix.c); pArray->AddNew<CPDF_Number>(matrix.d); pArray->AddNew<CPDF_Number>(matrix.e); pArray->AddNew<CPDF_Number>(matrix.f); - SetFor(key, pArray); } CFX_ByteString CPDF_Dictionary::MaybeIntern(const CFX_ByteString& str) { diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h index ebfd7e92ee..5d333808b9 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.h +++ b/core/fpdfapi/parser/cpdf_dictionary.h @@ -8,6 +8,7 @@ #define CORE_FPDFAPI_PARSER_CPDF_DICTIONARY_H_ #include <map> +#include <memory> #include <set> #include "core/fpdfapi/parser/cpdf_object.h" @@ -21,8 +22,8 @@ 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; + using const_iterator = + std::map<CFX_ByteString, std::unique_ptr<CPDF_Object>>::const_iterator; CPDF_Dictionary(); explicit CPDF_Dictionary(const CFX_WeakPtr<CFX_ByteStringPool>& pPool); @@ -60,19 +61,27 @@ class CPDF_Dictionary : public CPDF_Object { bool IsSignatureDict() const; // Set* functions invalidate iterators for the element with the key |key|. - void SetFor(const CFX_ByteString& key, CPDF_Object* pObj); - void SetBooleanFor(const CFX_ByteString& key, bool bValue); - 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 SetReferenceFor(const CFX_ByteString& key, - CPDF_IndirectObjectHolder* pDoc, - CPDF_Object* pObj); + // Takes ownership of |pObj|, returns an unowned pointer to it. + CPDF_Object* SetFor(const CFX_ByteString& key, + std::unique_ptr<CPDF_Object> pObj); + + // Creates a new object owned by the dictionary and returns an unowned + // pointer to it. + template <typename T, typename... Args> + typename std::enable_if<!CanInternStrings<T>::value, T*>::type SetNewFor( + const CFX_ByteString& key, + Args... args) { + return static_cast<T*>(SetFor(key, pdfium::MakeUnique<T>(args...))); + } + template <typename T, typename... Args> + typename std::enable_if<CanInternStrings<T>::value, T*>::type SetNewFor( + const CFX_ByteString& key, + Args... args) { + return static_cast<T*>( + SetFor(key, pdfium::MakeUnique<T>(m_pPool, args...))); + } + // Convenience functions to convert native objects to array form. void SetRectFor(const CFX_ByteString& key, const CFX_FloatRect& rect); void SetMatrixFor(const CFX_ByteString& key, const CFX_Matrix& matrix); @@ -85,8 +94,6 @@ class CPDF_Dictionary : public CPDF_Object { // 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(); } @@ -99,7 +106,7 @@ class CPDF_Dictionary : public CPDF_Object { std::set<const CPDF_Object*>* visited) const override; CFX_WeakPtr<CFX_ByteStringPool> m_pPool; - std::map<CFX_ByteString, CPDF_Object*> m_Map; + std::map<CFX_ByteString, std::unique_ptr<CPDF_Object>> m_Map; }; inline CPDF_Dictionary* ToDictionary(CPDF_Object* obj) { diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp index bafeefe6fc..97f55f872d 100644 --- a/core/fpdfapi/parser/cpdf_document.cpp +++ b/core/fpdfapi/parser/cpdf_document.cpp @@ -8,6 +8,7 @@ #include <memory> #include <set> +#include <utility> #include <vector> #include "core/fpdfapi/cpdf_modulemgr.h" @@ -22,6 +23,7 @@ #include "core/fpdfapi/parser/cpdf_number.h" #include "core/fpdfapi/parser/cpdf_parser.h" #include "core/fpdfapi/parser/cpdf_reference.h" +#include "core/fpdfapi/parser/cpdf_string.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/render/cpdf_docrenderdata.h" #include "core/fpdfapi/render/render_int.h" @@ -265,7 +267,7 @@ int CountPages(CPDF_Dictionary* pPages, count++; } } - pPages->SetIntegerFor("Count", count); + pPages->SetNewFor<CPDF_Number>("Count", count); return count; } @@ -304,11 +306,11 @@ void ProcessNonbCJK(CPDF_Dictionary* pBaseDict, 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); + pBaseDict->SetNewFor<CPDF_Name>("Subtype", "TrueType"); + pBaseDict->SetNewFor<CPDF_Name>("BaseFont", basefont); + pBaseDict->SetNewFor<CPDF_Number>("FirstChar", 32); + pBaseDict->SetNewFor<CPDF_Number>("LastChar", 255); + pBaseDict->SetFor("Widths", pdfium::WrapUnique(pWidths)); } std::unique_ptr<CPDF_Dictionary> CalculateFontDesc(CPDF_Document* pDoc, @@ -321,14 +323,14 @@ std::unique_ptr<CPDF_Dictionary> CalculateFontDesc(CPDF_Document* pDoc, int32_t stemV) { auto pFontDesc = pdfium::MakeUnique<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); + pFontDesc->SetNewFor<CPDF_Name>("Type", "FontDescriptor"); + pFontDesc->SetNewFor<CPDF_Name>("FontName", basefont); + pFontDesc->SetNewFor<CPDF_Number>("Flags", flags); + pFontDesc->SetFor("FontBBox", pdfium::WrapUnique(bbox)); + pFontDesc->SetNewFor<CPDF_Number>("ItalicAngle", italicangle); + pFontDesc->SetNewFor<CPDF_Number>("Ascent", ascend); + pFontDesc->SetNewFor<CPDF_Number>("Descent", descend); + pFontDesc->SetNewFor<CPDF_Number>("StemV", stemV); return pFontDesc; } @@ -649,19 +651,19 @@ CPDF_Image* CPDF_Document::LoadImageFromPageData(uint32_t dwStreamObjNum) { void CPDF_Document::CreateNewDoc() { ASSERT(!m_pRootDict && !m_pInfoDict); m_pRootDict = NewIndirect<CPDF_Dictionary>(); - m_pRootDict->SetNameFor("Type", "Catalog"); + m_pRootDict->SetNewFor<CPDF_Name>("Type", "Catalog"); 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); + pPages->SetNewFor<CPDF_Name>("Type", "Pages"); + pPages->SetNewFor<CPDF_Number>("Count", 0); + pPages->SetNewFor<CPDF_Array>("Kids"); + m_pRootDict->SetNewFor<CPDF_Reference>("Pages", this, pPages->GetObjNum()); m_pInfoDict = NewIndirect<CPDF_Dictionary>(); } CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) { CPDF_Dictionary* pDict = NewIndirect<CPDF_Dictionary>(); - pDict->SetNameFor("Type", "Page"); + pDict->SetNewFor<CPDF_Name>("Type", "Page"); uint32_t dwObjNum = pDict->GetObjNum(); if (!InsertNewPage(iPage, pDict)) { DeleteIndirectObject(dwObjNum); @@ -688,11 +690,12 @@ bool CPDF_Document::InsertDeletePDFPage(CPDF_Dictionary* pPages, } if (bInsert) { pKidList->InsertNewAt<CPDF_Reference>(i, this, pPageDict->GetObjNum()); - pPageDict->SetReferenceFor("Parent", this, pPages->GetObjNum()); + pPageDict->SetNewFor<CPDF_Reference>("Parent", this, + pPages->GetObjNum()); } else { pKidList->RemoveAt(i); } - pPages->SetIntegerFor( + pPages->SetNewFor<CPDF_Number>( "Count", pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1)); ResetTraversal(); break; @@ -709,8 +712,8 @@ bool CPDF_Document::InsertDeletePDFPage(CPDF_Dictionary* pPages, if (!InsertDeletePDFPage(pKid, nPagesToGo, pPageDict, bInsert, pVisited)) return false; - pPages->SetIntegerFor("Count", - pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1)); + pPages->SetNewFor<CPDF_Number>( + "Count", pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1)); break; } return true; @@ -728,13 +731,11 @@ bool CPDF_Document::InsertNewPage(int iPage, CPDF_Dictionary* pPageDict) { if (iPage == nPages) { CPDF_Array* pPagesList = pPages->GetArrayFor("Kids"); - if (!pPagesList) { - pPagesList = new CPDF_Array; - pPages->SetFor("Kids", pPagesList); - } + if (!pPagesList) + pPagesList = pPages->SetNewFor<CPDF_Array>("Kids"); pPagesList->AddNew<CPDF_Reference>(this, pPageDict->GetObjNum()); - pPages->SetIntegerFor("Count", nPages + 1); - pPageDict->SetReferenceFor("Parent", this, pPages->GetObjNum()); + pPages->SetNewFor<CPDF_Number>("Count", nPages + 1); + pPageDict->SetNewFor<CPDF_Reference>("Parent", this, pPages->GetObjNum()); ResetTraversal(); } else { std::set<CPDF_Dictionary*> stack = {pPages}; @@ -780,9 +781,9 @@ size_t CPDF_Document::CalculateEncodingDict(int charset, return i; CPDF_Dictionary* pEncodingDict = NewIndirect<CPDF_Dictionary>(); - pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); + pEncodingDict->SetNewFor<CPDF_Name>("BaseEncoding", "WinAnsiEncoding"); - CPDF_Array* pArray = new CPDF_Array; + CPDF_Array* pArray = pEncodingDict->SetNewFor<CPDF_Array>("Differences"); pArray->AddNew<CPDF_Number>(128); const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; @@ -790,8 +791,8 @@ size_t CPDF_Document::CalculateEncodingDict(int charset, CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); pArray->AddNew<CPDF_Name>(name.IsEmpty() ? ".notdef" : name); } - pEncodingDict->SetFor("Differences", pArray); - pBaseDict->SetReferenceFor("Encoding", this, pEncodingDict); + pBaseDict->SetNewFor<CPDF_Reference>("Encoding", this, + pEncodingDict->GetObjNum()); return i; } @@ -805,7 +806,7 @@ CPDF_Dictionary* CPDF_Document::ProcessbCJK( CFX_ByteString cmap; CFX_ByteString ordering; int supplement = 0; - CPDF_Array* pWidthArray = new CPDF_Array; + CPDF_Array* pWidthArray = pFontDict->SetNewFor<CPDF_Array>("W"); switch (charset) { case FXFONT_CHINESEBIG5_CHARSET: cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H"; @@ -844,20 +845,20 @@ CPDF_Dictionary* CPDF_Document::ProcessbCJK( 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(GetByteStringPool()); - 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); + pBaseDict->SetNewFor<CPDF_Name>("Subtype", "Type0"); + pBaseDict->SetNewFor<CPDF_Name>("BaseFont", basefont); + pBaseDict->SetNewFor<CPDF_Name>("Encoding", cmap); + pFontDict->SetNewFor<CPDF_Name>("Type", "Font"); + pFontDict->SetNewFor<CPDF_Name>("Subtype", "CIDFontType2"); + pFontDict->SetNewFor<CPDF_Name>("BaseFont", basefont); + + CPDF_Dictionary* pCIDSysInfo = + pFontDict->SetNewFor<CPDF_Dictionary>("CIDSystemInfo"); + pCIDSysInfo->SetNewFor<CPDF_String>("Registry", "Adobe", false); + pCIDSysInfo->SetNewFor<CPDF_String>("Ordering", ordering, false); + pCIDSysInfo->SetNewFor<CPDF_Number>("Supplement", supplement); + + CPDF_Array* pArray = pBaseDict->SetNewFor<CPDF_Array>("DescendantFonts"); pArray->AddNew<CPDF_Reference>(this, pFontDict->GetObjNum()); return pFontDict; } @@ -877,7 +878,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) { false, false, charset == FXFONT_SYMBOL_CHARSET); CPDF_Dictionary* pBaseDict = NewIndirect<CPDF_Dictionary>(); - pBaseDict->SetNameFor("Type", "Font"); + pBaseDict->SetNewFor<CPDF_Name>("Type", "Font"); std::unique_ptr<CFX_UnicodeEncoding> pEncoding( new CFX_UnicodeEncoding(pFont)); CPDF_Dictionary* pFontDict = pBaseDict; @@ -890,7 +891,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) { } if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET || charset == FXFONT_SYMBOL_CHARSET) { - pBaseDict->SetNameFor("Encoding", "WinAnsiEncoding"); + pBaseDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding"); for (int charcode = 128; charcode <= 255; charcode++) { int glyph_index = pEncoding->GlyphFromCharCode(charcode); int char_width = pFont->GetGlyphWidth(glyph_index); @@ -944,7 +945,8 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) { CPDF_Dictionary* pFontDesc = ToDictionary(AddIndirectObject( CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(), pFont->GetDescent(), pBBox, nStemV))); - pFontDict->SetReferenceFor("FontDescriptor", this, pFontDesc); + pFontDict->SetNewFor<CPDF_Reference>("FontDescriptor", this, + pFontDesc->GetObjNum()); return LoadFont(pBaseDict); } @@ -1007,13 +1009,13 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, FX_Free(tm_buf); basefont.Replace(" ", ""); CPDF_Dictionary* pBaseDict = NewIndirect<CPDF_Dictionary>(); - pBaseDict->SetNameFor("Type", "Font"); + pBaseDict->SetNewFor<CPDF_Name>("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"); + pBaseDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding"); } else { CalculateEncodingDict(pLogFont->lfCharSet, pBaseDict); } @@ -1037,9 +1039,10 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, std::unique_ptr<CPDF_Dictionary> pFontDesc = CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend, pBBox, pLogFont->lfWeight / 5); - pFontDesc->SetIntegerFor("CapHeight", capheight); - pFontDict->SetReferenceFor("FontDescriptor", this, - AddIndirectObject(std::move(pFontDesc))); + pFontDesc->SetNewFor<CPDF_Number>("CapHeight", capheight); + pFontDict->SetNewFor<CPDF_Reference>( + "FontDescriptor", this, + AddIndirectObject(std::move(pFontDesc))->GetObjNum()); hFont = SelectObject(hDC, hFont); DeleteObject(hFont); DeleteDC(hDC); diff --git a/core/fpdfapi/parser/cpdf_document_unittest.cpp b/core/fpdfapi/parser/cpdf_document_unittest.cpp index df90875c3c..94cef559f0 100644 --- a/core/fpdfapi/parser/cpdf_document_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_document_unittest.cpp @@ -5,13 +5,17 @@ #include "core/fpdfapi/parser/cpdf_document.h" #include <memory> +#include <utility> #include "core/fpdfapi/cpdf_modulemgr.h" #include "core/fpdfapi/parser/cpdf_array.h" +#include "core/fpdfapi/parser/cpdf_boolean.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_linearized_header.h" +#include "core/fpdfapi/parser/cpdf_number.h" #include "core/fpdfapi/parser/cpdf_parser.h" #include "core/fpdfapi/parser/cpdf_reference.h" +#include "core/fpdfapi/parser/cpdf_string.h" #include "core/fxcrt/fx_memory.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/base/ptr_util.h" @@ -23,18 +27,20 @@ CPDF_Dictionary* CreatePageTreeNode(std::unique_ptr<CPDF_Array> kids, int count) { CPDF_Array* pUnowned = pDoc->AddIndirectObject(std::move(kids))->AsArray(); CPDF_Dictionary* pageNode = pDoc->NewIndirect<CPDF_Dictionary>(); - pageNode->SetStringFor("Type", "Pages"); - pageNode->SetReferenceFor("Kids", pDoc, pUnowned); - pageNode->SetIntegerFor("Count", count); - for (size_t i = 0; i < pUnowned->GetCount(); i++) - pUnowned->GetDictAt(i)->SetReferenceFor("Parent", pDoc, pageNode); + pageNode->SetNewFor<CPDF_String>("Type", "Pages", false); + pageNode->SetNewFor<CPDF_Reference>("Kids", pDoc, pUnowned->GetObjNum()); + pageNode->SetNewFor<CPDF_Number>("Count", count); + for (size_t i = 0; i < pUnowned->GetCount(); i++) { + pUnowned->GetDictAt(i)->SetNewFor<CPDF_Reference>("Parent", pDoc, + pageNode->GetObjNum()); + } return pageNode; } std::unique_ptr<CPDF_Dictionary> CreateNumberedPage(size_t number) { auto page = pdfium::MakeUnique<CPDF_Dictionary>(); - page->SetStringFor("Type", "Page"); - page->SetIntegerFor("PageNumbering", number); + page->SetNewFor<CPDF_String>("Type", "Page", false); + page->SetNewFor<CPDF_Number>("PageNumbering", static_cast<int>(number)); return page; } @@ -79,7 +85,8 @@ class CPDF_TestDocumentForPages : public CPDF_Document { CreatePageTreeNode(std::move(allPages), this, 7); m_pOwnedRootDict = pdfium::MakeUnique<CPDF_Dictionary>(); - m_pOwnedRootDict->SetReferenceFor("Pages", this, pagesDict); + m_pOwnedRootDict->SetNewFor<CPDF_Reference>("Pages", this, + pagesDict->GetObjNum()); m_pRootDict = m_pOwnedRootDict.get(); m_PageList.SetSize(7); } @@ -102,7 +109,8 @@ class CPDF_TestDocumentWithPageWithoutPageNum : public CPDF_Document { CPDF_Dictionary* pagesDict = CreatePageTreeNode(std::move(allPages), this, 3); m_pOwnedRootDict.reset(new CPDF_Dictionary()); - m_pOwnedRootDict->SetReferenceFor("Pages", this, pagesDict->GetObjNum()); + m_pOwnedRootDict->SetNewFor<CPDF_Reference>("Pages", this, + pagesDict->GetObjNum()); m_pRootDict = m_pOwnedRootDict.get(); m_PageList.SetSize(3); } @@ -194,9 +202,9 @@ TEST_F(cpdf_document_test, UseCachedPageObjNumIfHaveNotPagesDict) { // (case, when hint table is used to page check in CPDF_DataAvail). CPDF_Document document(pdfium::MakeUnique<CPDF_Parser>()); auto dict = pdfium::MakeUnique<CPDF_Dictionary>(); - dict->SetBooleanFor("Linearized", true); + dict->SetNewFor<CPDF_Boolean>("Linearized", true); const int page_count = 100; - dict->SetIntegerFor("N", page_count); + dict->SetNewFor<CPDF_Number>("N", page_count); TestLinearized linearized(dict.get()); document.LoadLinearizedDoc(&linearized); ASSERT_EQ(page_count, document.GetPageCount()); diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp index 2de6256912..86645934bf 100644 --- a/core/fpdfapi/parser/cpdf_object_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp @@ -14,6 +14,7 @@ #include <memory> #include <string> +#include <utility> #include <vector> #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h" @@ -53,8 +54,8 @@ class PDFObjectsTest : public testing::Test { 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"); + CPDF_String* str_reg_obj = new CPDF_String(nullptr, L"A simple test"); + CPDF_String* str_spec_obj = new CPDF_String(nullptr, L"\t\n"); // Name object. CPDF_Name* name_obj = new CPDF_Name(nullptr, "space"); // Array object. @@ -63,16 +64,16 @@ class PDFObjectsTest : public testing::Test { m_ArrayObj->InsertNewAt<CPDF_Name>(1, "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)); + m_DictObj->SetNewFor<CPDF_Boolean>("bool", false); + m_DictObj->SetNewFor<CPDF_Number>("num", 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)); + m_StreamDictObj->SetNewFor<CPDF_String>("key1", L" test dict"); + m_StreamDictObj->SetNewFor<CPDF_Number>("key2", -1); CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj); // Null Object. CPDF_Null* null_obj = new CPDF_Null; @@ -136,7 +137,7 @@ class PDFObjectsTest : public testing::Test { return false; for (CPDF_Dictionary::const_iterator it = dict1->begin(); it != dict1->end(); ++it) { - if (!Equal(it->second, dict2->GetObjectFor(it->first))) + if (!Equal(it->second.get(), dict2->GetObjectFor(it->first))) return false; } return true; @@ -555,7 +556,7 @@ TEST(PDFArrayTest, GetTypeAt) { char buf[33]; key.append(FXSYS_itoa(j, buf, 10)); int value = j + 200; - vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); + vals[i]->SetNewFor<CPDF_Number>(key.c_str(), value); } } for (size_t i = 0; i < 3; ++i) { @@ -581,7 +582,7 @@ TEST(PDFArrayTest, GetTypeAt) { char buf[33]; key.append(FXSYS_itoa(j, buf, 10)); int value = j + 200; - vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); + vals[i]->SetNewFor<CPDF_Number>(key.c_str(), value); } uint8_t content[] = "content: this is a stream"; size_t data_size = FX_ArraySize(content); @@ -620,12 +621,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(nullptr, "Linda", false)); - dict_val->SetFor("key2", new CPDF_String(nullptr, "Zoe", false)); + dict_val->SetNewFor<CPDF_String>("key1", "Linda", false); + dict_val->SetNewFor<CPDF_String>("key2", "Zoe", false); CPDF_Dictionary* stream_dict = new CPDF_Dictionary(); - stream_dict->SetFor("key1", new CPDF_String(nullptr, "John", false)); - stream_dict->SetFor("key2", new CPDF_String(nullptr, "King", false)); + stream_dict->SetNewFor<CPDF_String>("key1", "John", false); + stream_dict->SetNewFor<CPDF_String>("key2", "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. @@ -778,7 +779,7 @@ TEST(PDFArrayTest, ConvertIndirect) { TEST(PDFDictionaryTest, CloneDirectObject) { CPDF_IndirectObjectHolder objects_holder; std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary()); - dict->SetReferenceFor("foo", &objects_holder, 1234); + dict->SetNewFor<CPDF_Reference>("foo", &objects_holder, 1234); ASSERT_EQ(1U, dict->GetCount()); CPDF_Object* obj = dict->GetObjectFor("foo"); ASSERT_TRUE(obj); @@ -797,10 +798,12 @@ TEST(PDFDictionaryTest, CloneDirectObject) { TEST(PDFObjectTest, CloneCheckLoop) { { - // Create a dictionary/array pair with a reference loop. + // Create a dictionary/array pair with a reference loop. It takes + // some work to do this nowadays, in particular we need the + // anti-pattern pdfium::WrapUnique(arr.get()). auto arr_obj = pdfium::MakeUnique<CPDF_Array>(); CPDF_Dictionary* dict_obj = arr_obj->InsertNewAt<CPDF_Dictionary>(0); - dict_obj->SetFor("arr", arr_obj.get()); + dict_obj->SetFor("arr", pdfium::WrapUnique(arr_obj.get())); // Clone this object to see whether stack overflow will be triggered. std::unique_ptr<CPDF_Array> cloned_array = ToArray(arr_obj->Clone()); // Cloned object should be the same as the original. @@ -814,11 +817,9 @@ TEST(PDFObjectTest, CloneCheckLoop) { } { // Create a dictionary/stream pair with a reference loop. - CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); - std::unique_ptr<CPDF_Stream> stream_obj( - new CPDF_Stream(nullptr, 0, dict_obj)); - dict_obj->SetFor("stream", stream_obj.get()); - + auto dict_obj = pdfium::MakeUnique<CPDF_Dictionary>(); + CPDF_Stream* stream_obj = + dict_obj->SetNewFor<CPDF_Stream>("stream", nullptr, 0, dict_obj.get()); // Clone this object to see whether stack overflow will be triggered. std::unique_ptr<CPDF_Stream> cloned_stream = ToStream(stream_obj->Clone()); // Cloned object should be the same as the original. @@ -837,7 +838,7 @@ TEST(PDFObjectTest, CloneCheckLoop) { arr_obj->InsertNewAt<CPDF_Reference>(0, &objects_holder, dict_obj->GetObjNum()); CPDF_Object* elem0 = arr_obj->GetObjectAt(0); - dict_obj->SetFor("arr", arr_obj.release()); + dict_obj->SetFor("arr", std::move(arr_obj)); EXPECT_EQ(1u, dict_obj->GetObjNum()); ASSERT_TRUE(elem0); ASSERT_TRUE(elem0->IsReference()); @@ -861,8 +862,7 @@ TEST(PDFObjectTest, CloneCheckLoop) { TEST(PDFDictionaryTest, ConvertIndirect) { CPDF_IndirectObjectHolder objects_holder; std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary); - CPDF_Object* pObj = new CPDF_Number(42); - dict->SetFor("clams", pObj); + CPDF_Object* pObj = dict->SetNewFor<CPDF_Number>("clams", 42); dict->ConvertToIndirectObjectFor("clams", &objects_holder); CPDF_Object* pRef = dict->GetObjectFor("clams"); CPDF_Object* pNum = dict->GetDirectObjectFor("clams"); diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp index c43614f628..5354417eda 100644 --- a/core/fpdfapi/parser/cpdf_parser.cpp +++ b/core/fpdfapi/parser/cpdf_parser.cpp @@ -6,6 +6,8 @@ #include "core/fpdfapi/parser/cpdf_parser.h" +#include <algorithm> +#include <utility> #include <vector> #include "core/fpdfapi/parser/cpdf_array.h" @@ -802,16 +804,15 @@ bool CPDF_Parser::RebuildCrossRef() { auto it = pTrailer->begin(); while (it != pTrailer->end()) { const CFX_ByteString& key = it->first; - CPDF_Object* pElement = it->second; + CPDF_Object* pElement = it->second.get(); ++it; uint32_t dwObjNum = pElement ? pElement->GetObjNum() : 0; if (dwObjNum) { - m_pTrailer->SetReferenceFor(key, m_pDocument, - dwObjNum); + m_pTrailer->SetNewFor<CPDF_Reference>( + key, m_pDocument, dwObjNum); } else { - m_pTrailer->SetFor(key, - pElement->Clone().release()); + m_pTrailer->SetFor(key, pElement->Clone()); } } } @@ -1075,7 +1076,7 @@ CPDF_Array* CPDF_Parser::GetIDArray() { if (CPDF_Reference* pRef = pID->AsReference()) { pID = ParseIndirectObject(nullptr, pRef->GetRefObjNum()).release(); - m_pTrailer->SetFor("ID", pID); + m_pTrailer->SetFor("ID", pdfium::WrapUnique(pID)); } return ToArray(pID); } diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp index bebda4ded8..f6f4aefa3f 100644 --- a/core/fpdfapi/parser/cpdf_security_handler.cpp +++ b/core/fpdfapi/parser/cpdf_security_handler.cpp @@ -8,12 +8,17 @@ #include <time.h> +#include <algorithm> +#include <utility> +#include <vector> + #include "core/fdrm/crypto/fx_crypt.h" #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_crypto_handler.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_object.h" #include "core/fpdfapi/parser/cpdf_parser.h" +#include "core/fpdfapi/parser/cpdf_string.h" namespace { @@ -570,7 +575,8 @@ void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len); } } - pEncryptDict->SetStringFor("O", CFX_ByteString(passcode, 32)); + pEncryptDict->SetNewFor<CPDF_String>("O", CFX_ByteString(passcode, 32), + false); } CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey, key_len, false, pIdArray); @@ -578,7 +584,8 @@ void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, uint8_t tempbuf[32]; FXSYS_memcpy(tempbuf, defpasscode, 32); CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len); - pEncryptDict->SetStringFor("U", CFX_ByteString(tempbuf, 32)); + pEncryptDict->SetNewFor<CPDF_String>("U", CFX_ByteString(tempbuf, 32), + false); } else { uint8_t md5[100]; CRYPT_MD5Start(md5); @@ -598,7 +605,8 @@ void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len); } CRYPT_MD5Generate(digest, 16, digest + 16); - pEncryptDict->SetStringFor("U", CFX_ByteString(digest, 32)); + pEncryptDict->SetNewFor<CPDF_String>("U", CFX_ByteString(digest, 32), + false); } } void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, @@ -645,7 +653,8 @@ void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict, CRYPT_SHA256Finish(sha, digest1); } FXSYS_memcpy(digest1 + 32, digest, 16); - pEncryptDict->SetStringFor(bOwner ? "O" : "U", CFX_ByteString(digest1, 48)); + pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U", + CFX_ByteString(digest1, 48), false); if (m_Revision >= 6) { Revision6_Hash(password, size, digest + 8, bOwner ? ukey.raw_str() : nullptr, digest1); @@ -665,8 +674,10 @@ void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict, CRYPT_AESSetIV(aes, iv); CRYPT_AESEncrypt(aes, digest1, key, 32); FX_Free(aes); - pEncryptDict->SetStringFor(bOwner ? "OE" : "UE", CFX_ByteString(digest1, 32)); + pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE", + CFX_ByteString(digest1, 32), false); } + void CPDF_SecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict, uint32_t permissions, bool bEncryptMetadata, @@ -691,5 +702,6 @@ void CPDF_SecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict, CRYPT_AESSetIV(aes, iv); CRYPT_AESEncrypt(aes, buf1, buf, 16); FX_Free(aes); - pEncryptDict->SetStringFor("Perms", CFX_ByteString(buf1, 16)); + pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16), + false); } diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp index 64261b14d3..fd7f08f688 100644 --- a/core/fpdfapi/parser/cpdf_stream.cpp +++ b/core/fpdfapi/parser/cpdf_stream.cpp @@ -7,6 +7,7 @@ #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" +#include "core/fpdfapi/parser/cpdf_number.h" #include "core/fpdfapi/parser/cpdf_stream_acc.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "third_party/base/numerics/safe_conversions.h" @@ -54,7 +55,7 @@ void CPDF_Stream::InitStream(const uint8_t* pData, FXSYS_memcpy(m_pDataBuf.get(), pData, size); m_dwSize = size; if (m_pDict) - m_pDict->SetIntegerFor("Length", m_dwSize); + m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(m_dwSize)); } void CPDF_Stream::InitStreamFromFile(IFX_SeekableReadStream* pFile, @@ -65,7 +66,7 @@ void CPDF_Stream::InitStreamFromFile(IFX_SeekableReadStream* pFile, m_pFile = pFile; m_dwSize = pdfium::base::checked_cast<uint32_t>(pFile->GetSize()); if (m_pDict) - m_pDict->SetIntegerFor("Length", m_dwSize); + m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(m_dwSize)); } std::unique_ptr<CPDF_Object> CPDF_Stream::Clone() const { @@ -96,7 +97,7 @@ void CPDF_Stream::SetData(const uint8_t* pData, uint32_t size) { m_dwSize = size; if (!m_pDict) m_pDict.reset(new CPDF_Dictionary()); - m_pDict->SetIntegerFor("Length", size); + m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(size)); m_pDict->RemoveFor("Filter"); m_pDict->RemoveFor("DecodeParms"); } diff --git a/core/fpdfapi/parser/cpdf_string.cpp b/core/fpdfapi/parser/cpdf_string.cpp index fd4ff04ff7..06bae54916 100644 --- a/core/fpdfapi/parser/cpdf_string.cpp +++ b/core/fpdfapi/parser/cpdf_string.cpp @@ -6,6 +6,8 @@ #include "core/fpdfapi/parser/cpdf_string.h" +#include <utility> + #include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "third_party/base/ptr_util.h" @@ -19,8 +21,11 @@ CPDF_String::CPDF_String(CFX_WeakPtr<CFX_ByteStringPool> pPool, m_String = pPool->Intern(m_String); } -CPDF_String::CPDF_String(const CFX_WideString& str) : m_bHex(false) { - m_String = PDF_EncodeText(str); +CPDF_String::CPDF_String(CFX_WeakPtr<CFX_ByteStringPool> pPool, + const CFX_WideString& str) + : m_String(PDF_EncodeText(str)), m_bHex(false) { + if (pPool) + m_String = pPool->Intern(m_String); } CPDF_String::~CPDF_String() {} diff --git a/core/fpdfapi/parser/cpdf_string.h b/core/fpdfapi/parser/cpdf_string.h index 616e3b593d..6698d8c5be 100644 --- a/core/fpdfapi/parser/cpdf_string.h +++ b/core/fpdfapi/parser/cpdf_string.h @@ -7,6 +7,8 @@ #ifndef CORE_FPDFAPI_PARSER_CPDF_STRING_H_ #define CORE_FPDFAPI_PARSER_CPDF_STRING_H_ +#include <memory> + #include "core/fpdfapi/parser/cpdf_object.h" #include "core/fxcrt/cfx_string_pool_template.h" #include "core/fxcrt/cfx_weak_ptr.h" @@ -19,7 +21,7 @@ class CPDF_String : public CPDF_Object { CPDF_String(CFX_WeakPtr<CFX_ByteStringPool> pPool, const CFX_ByteString& str, bool bHex); - explicit CPDF_String(const CFX_WideString& str); + CPDF_String(CFX_WeakPtr<CFX_ByteStringPool> pPool, const CFX_WideString& str); ~CPDF_String() override; // CPDF_Object: diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp index 6a38ce8c45..4a0fd3a408 100644 --- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp +++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp @@ -6,6 +6,8 @@ #include "core/fpdfapi/parser/cpdf_syntax_parser.h" +#include <algorithm> +#include <utility> #include <vector> #include "core/fpdfapi/cpdf_modulemgr.h" @@ -458,7 +460,7 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObject( continue; CFX_ByteString keyNoSlash(key.raw_str() + 1, key.GetLength() - 1); - pDict->SetFor(keyNoSlash, pObj.release()); + pDict->SetFor(keyNoSlash, std::move(pObj)); } // Only when this is a signature dictionary and has contents, we reset the @@ -466,8 +468,7 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObject( if (pDict->IsSignatureDict() && dwSignValuePos) { CFX_AutoRestorer<FX_FILESIZE> save_pos(&m_Pos); m_Pos = dwSignValuePos; - pDict->SetFor("Contents", - GetObject(pObjList, objnum, gennum, false).release()); + pDict->SetFor("Contents", GetObject(pObjList, objnum, gennum, false)); } FX_FILESIZE SavedPos = m_Pos; @@ -576,7 +577,7 @@ std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectForStrict( if (key.GetLength() > 1) { pDict->SetFor(CFX_ByteString(key.c_str() + 1, key.GetLength() - 1), - obj.release()); + std::move(obj)); } } @@ -722,7 +723,7 @@ std::unique_ptr<CPDF_Stream> CPDF_SyntaxParser::ReadStream( delete pDict; return nullptr; } - pDict->SetIntegerFor("Length", len); + pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(len)); } m_Pos = streamStartPos; } diff --git a/core/fpdfapi/parser/fpdf_parser_utility.cpp b/core/fpdfapi/parser/fpdf_parser_utility.cpp index 630754a23b..ef37d8f39e 100644 --- a/core/fpdfapi/parser/fpdf_parser_utility.cpp +++ b/core/fpdfapi/parser/fpdf_parser_utility.cpp @@ -7,6 +7,7 @@ #include "core/fpdfapi/parser/fpdf_parser_utility.h" #include "core/fpdfapi/parser/cpdf_array.h" +#include "core/fpdfapi/parser/cpdf_boolean.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_number.h" #include "core/fpdfapi/parser/cpdf_reference.h" @@ -193,7 +194,7 @@ CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj) { buf << "<<"; for (const auto& it : *p) { const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second; + CPDF_Object* pValue = it.second.get(); buf << "/" << PDF_NameEncode(key); if (pValue && !pValue->IsInline()) { buf << " " << pValue->GetObjNum() << " 0 R "; |