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 | |
parent | 430ab8363e77c48b2c2435af4d289f85e2be1b96 (diff) | |
download | pdfium-chromium/2926.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
49 files changed, 670 insertions, 680 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 "; diff --git a/core/fpdfdoc/cpdf_annot.cpp b/core/fpdfdoc/cpdf_annot.cpp index a213f51a6d..a7d2101364 100644 --- a/core/fpdfdoc/cpdf_annot.cpp +++ b/core/fpdfdoc/cpdf_annot.cpp @@ -9,6 +9,7 @@ #include "core/fpdfapi/page/cpdf_form.h" #include "core/fpdfapi/page/cpdf_page.h" #include "core/fpdfapi/parser/cpdf_array.h" +#include "core/fpdfapi/parser/cpdf_boolean.h" #include "core/fpdfapi/parser/cpdf_document.h" #include "core/fpdfapi/render/cpdf_rendercontext.h" #include "core/fpdfapi/render/cpdf_renderoptions.h" @@ -109,7 +110,7 @@ void CPDF_Annot::GenerateAPIfNeeded() { result = CPVT_GenerateAP::GenerateUnderlineAP(m_pDocument, m_pAnnotDict); if (result) { - m_pAnnotDict->SetBooleanFor(kPDFiumKey_HasGeneratedAP, result); + m_pAnnotDict->SetNewFor<CPDF_Boolean>(kPDFiumKey_HasGeneratedAP, result); m_bHasGeneratedAP = result; } } diff --git a/core/fpdfdoc/cpdf_annotlist.cpp b/core/fpdfdoc/cpdf_annotlist.cpp index 91cff454e3..e68e08a1f6 100644 --- a/core/fpdfdoc/cpdf_annotlist.cpp +++ b/core/fpdfdoc/cpdf_annotlist.cpp @@ -11,7 +11,10 @@ #include "core/fpdfapi/page/cpdf_page.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_reference.h" +#include "core/fpdfapi/parser/cpdf_string.h" #include "core/fpdfapi/render/cpdf_renderoptions.h" #include "core/fpdfdoc/cpdf_annot.h" #include "core/fpdfdoc/cpdf_interform.h" @@ -36,10 +39,11 @@ std::unique_ptr<CPDF_Annot> CreatePopupAnnot(CPDF_Annot* pAnnot, auto pAnnotDict = pdfium::MakeUnique<CPDF_Dictionary>(pDocument->GetByteStringPool()); - pAnnotDict->SetNameFor("Type", "Annot"); - pAnnotDict->SetNameFor("Subtype", "Popup"); - pAnnotDict->SetStringFor("T", pParentDict->GetStringFor("T")); - pAnnotDict->SetStringFor("Contents", sContents.UTF8Encode()); + pAnnotDict->SetNewFor<CPDF_Name>("Type", "Annot"); + pAnnotDict->SetNewFor<CPDF_Name>("Subtype", "Popup"); + pAnnotDict->SetNewFor<CPDF_String>("T", pParentDict->GetStringFor("T"), + false); + pAnnotDict->SetNewFor<CPDF_String>("Contents", sContents.UTF8Encode(), false); CFX_FloatRect rect = pParentDict->GetRectFor("Rect"); rect.Normalize(); @@ -47,7 +51,7 @@ std::unique_ptr<CPDF_Annot> CreatePopupAnnot(CPDF_Annot* pAnnot, popupRect.Translate(rect.left, rect.bottom - popupRect.Height()); pAnnotDict->SetRectFor("Rect", popupRect); - pAnnotDict->SetIntegerFor("F", 0); + pAnnotDict->SetNewFor<CPDF_Number>("F", 0); auto pPopupAnnot = pdfium::MakeUnique<CPDF_Annot>(std::move(pAnnotDict), pDocument); diff --git a/core/fpdfdoc/cpdf_filespec.cpp b/core/fpdfdoc/cpdf_filespec.cpp index 46b7f8a446..d6a66f7b73 100644 --- a/core/fpdfdoc/cpdf_filespec.cpp +++ b/core/fpdfdoc/cpdf_filespec.cpp @@ -7,7 +7,9 @@ #include "core/fpdfdoc/cpdf_filespec.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" +#include "core/fpdfapi/parser/cpdf_name.h" #include "core/fpdfapi/parser/cpdf_object.h" +#include "core/fpdfapi/parser/cpdf_string.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "core/fxcrt/fx_system.h" @@ -112,7 +114,7 @@ bool CPDF_FileSpec::GetFileName(CFX_WideString* csFileName) const { CPDF_FileSpec::CPDF_FileSpec(const CFX_WeakPtr<CFX_ByteStringPool>& pPool) { m_pObj = new CPDF_Dictionary(pPool); - m_pObj->AsDictionary()->SetNameFor("Type", "Filespec"); + m_pObj->AsDictionary()->SetNewFor<CPDF_Name>("Type", "Filespec"); } CFX_WideString CPDF_FileSpec::EncodeFileName(const CFX_WideStringC& filepath) { @@ -161,7 +163,8 @@ void CPDF_FileSpec::SetFileName(const CFX_WideStringC& wsFileName) { if (m_pObj->IsString()) { m_pObj->SetString(CFX_ByteString::FromUnicode(wsStr)); } else if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) { - pDict->SetStringFor("F", CFX_ByteString::FromUnicode(wsStr)); - pDict->SetStringFor("UF", PDF_EncodeText(wsStr)); + pDict->SetNewFor<CPDF_String>("F", CFX_ByteString::FromUnicode(wsStr), + false); + pDict->SetNewFor<CPDF_String>("UF", PDF_EncodeText(wsStr), false); } } diff --git a/core/fpdfdoc/cpdf_filespec_unittest.cpp b/core/fpdfdoc/cpdf_filespec_unittest.cpp index 4da5019314..d164165f00 100644 --- a/core/fpdfdoc/cpdf_filespec_unittest.cpp +++ b/core/fpdfdoc/cpdf_filespec_unittest.cpp @@ -67,7 +67,8 @@ TEST(cpdf_filespec, GetFileName) { L"/docs/test.pdf" #endif }; - std::unique_ptr<CPDF_Object> str_obj(new CPDF_String(test_data.input)); + std::unique_ptr<CPDF_Object> str_obj( + new CPDF_String(nullptr, test_data.input)); CPDF_FileSpec file_spec(str_obj.get()); CFX_WideString file_name; EXPECT_TRUE(file_spec.GetFileName(&file_name)); @@ -102,13 +103,13 @@ TEST(cpdf_filespec, GetFileName) { CPDF_FileSpec file_spec(dict_obj.get()); CFX_WideString file_name; for (int i = 0; i < 5; ++i) { - dict_obj->SetFor(keywords[i], new CPDF_String(test_data[i].input)); + dict_obj->SetNewFor<CPDF_String>(keywords[i], test_data[i].input); EXPECT_TRUE(file_spec.GetFileName(&file_name)); EXPECT_TRUE(file_name == test_data[i].expected); } // With all the former fields and 'FS' field suggests 'URL' type. - dict_obj->SetStringFor("FS", "URL"); + dict_obj->SetNewFor<CPDF_String>("FS", "URL", false); EXPECT_TRUE(file_spec.GetFileName(&file_name)); // Url string is not decoded. EXPECT_TRUE(file_name == test_data[4].input); @@ -136,7 +137,7 @@ TEST(cpdf_filespec, SetFileName) { #endif }; // String object. - std::unique_ptr<CPDF_Object> str_obj(new CPDF_String(L"babababa")); + std::unique_ptr<CPDF_Object> str_obj(new CPDF_String(nullptr, L"babababa")); CPDF_FileSpec file_spec1(str_obj.get()); file_spec1.SetFileName(test_data.input); // Check internal object value. diff --git a/core/fpdfdoc/cpdf_formcontrol.cpp b/core/fpdfdoc/cpdf_formcontrol.cpp index b01784b8dd..54edb4910c 100644 --- a/core/fpdfdoc/cpdf_formcontrol.cpp +++ b/core/fpdfdoc/cpdf_formcontrol.cpp @@ -11,6 +11,7 @@ #include "core/fpdfapi/page/cpdf_form.h" #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_document.h" +#include "core/fpdfapi/parser/cpdf_name.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "core/fpdfapi/render/cpdf_rendercontext.h" @@ -61,14 +62,14 @@ void CPDF_FormControl::SetOnStateName(const CFX_ByteString& csOn) { CFX_ByteString csAS = m_pWidgetDict->GetStringFor("AS", "Off"); if (csAS != "Off") - m_pWidgetDict->SetNameFor("AS", csValue); + m_pWidgetDict->SetNewFor<CPDF_Name>("AS", csValue); CPDF_Dictionary* pAP = m_pWidgetDict->GetDictFor("AP"); if (!pAP) return; for (const auto& it : *pAP) { - CPDF_Object* pObj1 = it.second; + CPDF_Object* pObj1 = it.second.get(); if (!pObj1) continue; @@ -80,7 +81,7 @@ void CPDF_FormControl::SetOnStateName(const CFX_ByteString& csOn) { auto subdict_it = pSubDict->begin(); while (subdict_it != pSubDict->end()) { const CFX_ByteString& csKey2 = subdict_it->first; - CPDF_Object* pObj2 = subdict_it->second; + CPDF_Object* pObj2 = subdict_it->second.get(); ++subdict_it; if (!pObj2) continue; @@ -155,7 +156,7 @@ void CPDF_FormControl::CheckControl(bool bChecked) { csAS = csOn; if (csOldAS == csAS) return; - m_pWidgetDict->SetNameFor("AS", csAS); + m_pWidgetDict->SetNewFor<CPDF_Name>("AS", csAS); } void CPDF_FormControl::DrawControl(CFX_RenderDevice* pDevice, diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp index 3a2213f1ae..cc7054dfaf 100644 --- a/core/fpdfdoc/cpdf_formfield.cpp +++ b/core/fpdfdoc/cpdf_formfield.cpp @@ -6,11 +6,14 @@ #include "core/fpdfdoc/cpdf_formfield.h" +#include <memory> #include <set> +#include <utility> #include "core/fpdfapi/parser/cfdf_document.h" #include "core/fpdfapi/parser/cpdf_array.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_simple_parser.h" #include "core/fpdfapi/parser/cpdf_string.h" @@ -223,11 +226,9 @@ bool CPDF_FormField::ResetField(bool bNotify) { if (!pClone) return false; - m_pDict->SetFor("V", pClone.release()); - if (pRV) { - std::unique_ptr<CPDF_Object> pCloneR = pDV->Clone(); - m_pDict->SetFor("RV", pCloneR.release()); - } + m_pDict->SetFor("V", std::move(pClone)); + if (pRV) + m_pDict->SetFor("RV", pDV->Clone()); } else { m_pDict->RemoveFor("V"); m_pDict->RemoveFor("RV"); @@ -361,15 +362,16 @@ bool CPDF_FormField::SetValue(const CFX_WideString& value, if (bNotify && !NotifyBeforeValueChange(csValue)) return false; + CFX_ByteString key(bDefault ? "DV" : "V"); int iIndex = FindOptionValue(csValue); if (iIndex < 0) { CFX_ByteString bsEncodeText = PDF_EncodeText(csValue); - m_pDict->SetStringFor(bDefault ? "DV" : "V", bsEncodeText); + m_pDict->SetNewFor<CPDF_String>(key, bsEncodeText, false); if (m_Type == RichText && !bDefault) - m_pDict->SetStringFor("RV", bsEncodeText); + m_pDict->SetNewFor<CPDF_String>("RV", bsEncodeText, false); m_pDict->RemoveFor("I"); } else { - m_pDict->SetStringFor(bDefault ? "DV" : "V", PDF_EncodeText(csValue)); + m_pDict->SetNewFor<CPDF_String>(key, PDF_EncodeText(csValue), false); if (!bDefault) { ClearSelection(); SetItemSelection(iIndex, true); @@ -549,22 +551,20 @@ bool CPDF_FormField::SetItemSelection(int index, bool bSelected, bool bNotify) { if (GetType() == ListBox) { SelectOption(index, true); if (!(m_Flags & kFormListMultiSelect)) { - m_pDict->SetStringFor("V", PDF_EncodeText(opt_value)); + m_pDict->SetNewFor<CPDF_String>("V", PDF_EncodeText(opt_value), false); } else { - CPDF_Array* pArray = new CPDF_Array; + CPDF_Array* pArray = m_pDict->SetNewFor<CPDF_Array>("V"); for (int i = 0; i < CountOptions(); i++) { if (i == index || IsItemSelected(i)) { opt_value = GetOptionValue(i); pArray->AddNew<CPDF_String>(PDF_EncodeText(opt_value), false); } } - m_pDict->SetFor("V", pArray); } } else { - m_pDict->SetStringFor("V", PDF_EncodeText(opt_value)); - CPDF_Array* pI = new CPDF_Array; + m_pDict->SetNewFor<CPDF_String>("V", PDF_EncodeText(opt_value), false); + CPDF_Array* pI = m_pDict->SetNewFor<CPDF_Array>("I"); pI->AddNew<CPDF_Number>(index); - m_pDict->SetFor("I", pI); } } else { CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V"); @@ -583,7 +583,7 @@ bool CPDF_FormField::SetItemSelection(int index, bool bSelected, bool bNotify) { } } if (pArray->GetCount() > 0) - m_pDict->SetFor("V", pArray.release()); // std::move someday + m_pDict->SetFor("V", std::move(pArray)); } } else { m_pDict->RemoveFor("V"); @@ -675,12 +675,9 @@ int CPDF_FormField::InsertOption(CFX_WideString csOptLabel, CFX_ByteString csStr = PDF_EncodeText(csOptLabel.c_str(), csOptLabel.GetLength()); - CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "Opt"); - CPDF_Array* pOpt = ToArray(pValue); - if (!pOpt) { - pOpt = new CPDF_Array; - m_pDict->SetFor("Opt", pOpt); - } + CPDF_Array* pOpt = ToArray(FPDF_GetFieldAttr(m_pDict, "Opt")); + if (!pOpt) + pOpt = m_pDict->SetNewFor<CPDF_Array>("Opt"); int iCount = pdfium::base::checked_cast<int>(pOpt->GetCount()); if (index >= iCount) { @@ -755,19 +752,19 @@ bool CPDF_FormField::CheckControl(int iControlIndex, CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pDict, "Opt"); if (!ToArray(pOpt)) { if (bChecked) { - m_pDict->SetNameFor("V", csBExport); + m_pDict->SetNewFor<CPDF_Name>("V", csBExport); } else { CFX_ByteString csV; CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict, "V"); if (pV) csV = pV->GetString(); if (csV == csBExport) - m_pDict->SetNameFor("V", "Off"); + m_pDict->SetNewFor<CPDF_Name>("V", "Off"); } } else if (bChecked) { CFX_ByteString csIndex; csIndex.Format("%d", iControlIndex); - m_pDict->SetNameFor("V", csIndex); + m_pDict->SetNewFor<CPDF_Name>("V", csIndex); } if (bNotify && m_pForm->m_pFormNotify) m_pForm->m_pFormNotify->AfterCheckedStatusChange(this); @@ -848,8 +845,7 @@ bool CPDF_FormField::SelectOption(int iOptIndex, bool bSelected, bool bNotify) { if (!bSelected) return true; - pArray = new CPDF_Array; - m_pDict->SetFor("I", pArray); + pArray = m_pDict->SetNewFor<CPDF_Array>("I"); } bool bReturn = false; diff --git a/core/fpdfdoc/cpdf_formfield_unittest.cpp b/core/fpdfdoc/cpdf_formfield_unittest.cpp index f69df1d064..4aeda84c88 100644 --- a/core/fpdfdoc/cpdf_formfield_unittest.cpp +++ b/core/fpdfdoc/cpdf_formfield_unittest.cpp @@ -4,6 +4,8 @@ #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h" +#include "core/fpdfapi/parser/cpdf_name.h" +#include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfdoc/cpdf_formfield.h" #include "testing/gtest/include/gtest/gtest.h" @@ -13,29 +15,28 @@ TEST(cpdf_formfield, FPDF_GetFullName) { CPDF_IndirectObjectHolder obj_holder; CPDF_Dictionary* root = obj_holder.NewIndirect<CPDF_Dictionary>(); - root->SetNameFor("T", "foo"); + root->SetNewFor<CPDF_Name>("T", "foo"); name = FPDF_GetFullName(root); EXPECT_STREQ("foo", name.UTF8Encode().c_str()); CPDF_Dictionary* dict1 = obj_holder.NewIndirect<CPDF_Dictionary>(); - root->SetReferenceFor("Parent", &obj_holder, dict1); - dict1->SetNameFor("T", "bar"); + root->SetNewFor<CPDF_Reference>("Parent", &obj_holder, dict1->GetObjNum()); + dict1->SetNewFor<CPDF_Name>("T", "bar"); name = FPDF_GetFullName(root); EXPECT_STREQ("bar.foo", name.UTF8Encode().c_str()); - CPDF_Dictionary* dict2 = new CPDF_Dictionary(); - dict1->SetFor("Parent", dict2); + CPDF_Dictionary* dict2 = dict1->SetNewFor<CPDF_Dictionary>("Parent"); name = FPDF_GetFullName(root); EXPECT_STREQ("bar.foo", name.UTF8Encode().c_str()); CPDF_Dictionary* dict3 = obj_holder.NewIndirect<CPDF_Dictionary>(); - dict2->SetReferenceFor("Parent", &obj_holder, dict3); + dict2->SetNewFor<CPDF_Reference>("Parent", &obj_holder, dict3->GetObjNum()); - dict3->SetNameFor("T", "qux"); + dict3->SetNewFor<CPDF_Name>("T", "qux"); name = FPDF_GetFullName(root); EXPECT_STREQ("qux.bar.foo", name.UTF8Encode().c_str()); - dict3->SetReferenceFor("Parent", &obj_holder, root->GetObjNum()); + dict3->SetNewFor<CPDF_Reference>("Parent", &obj_holder, root->GetObjNum()); name = FPDF_GetFullName(root); EXPECT_STREQ("qux.bar.foo", name.UTF8Encode().c_str()); name = FPDF_GetFullName(dict1); diff --git a/core/fpdfdoc/cpdf_interform.cpp b/core/fpdfdoc/cpdf_interform.cpp index f541d7087c..377a360d9e 100644 --- a/core/fpdfdoc/cpdf_interform.cpp +++ b/core/fpdfdoc/cpdf_interform.cpp @@ -4,6 +4,9 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +#include "core/fpdfdoc/cpdf_interform.h" + +#include <utility> #include <vector> #include "core/fpdfapi/font/cpdf_font.h" @@ -12,11 +15,11 @@ #include "core/fpdfapi/parser/cfdf_document.h" #include "core/fpdfapi/parser/cpdf_array.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_string.h" #include "core/fpdfdoc/cpdf_filespec.h" #include "core/fpdfdoc/cpdf_formcontrol.h" -#include "core/fpdfdoc/cpdf_interform.h" #include "core/fxge/cfx_substfont.h" #include "core/fxge/fx_font.h" #include "third_party/base/stl_util.h" @@ -60,8 +63,8 @@ void InitDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument) { if (!pFormDict) { pFormDict = pDocument->NewIndirect<CPDF_Dictionary>(); - pDocument->GetRoot()->SetReferenceFor("AcroForm", pDocument, - pFormDict->GetObjNum()); + pDocument->GetRoot()->SetNewFor<CPDF_Reference>("AcroForm", pDocument, + pFormDict->GetObjNum()); } CFX_ByteString csDA; @@ -94,7 +97,7 @@ void InitDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument) { csDA += "0 g"; if (!pFormDict->KeyExist("DA")) - pFormDict->SetStringFor("DA", csDA); + pFormDict->SetNewFor<CPDF_String>("DA", csDA, false); } CPDF_Font* GetFont(CPDF_Dictionary* pFormDict, @@ -138,11 +141,10 @@ CPDF_Font* GetNativeFont(CPDF_Dictionary* pFormDict, for (const auto& it : *pFonts) { const CFX_ByteString& csKey = it.first; - CPDF_Object* pObj = it.second; - if (!pObj) + if (!it.second) continue; - CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect()); + CPDF_Dictionary* pElement = ToDictionary(it.second->GetDirect()); if (!pElement) continue; if (pElement->GetStringFor("Type") != "Font") @@ -179,11 +181,9 @@ bool FindFont(CPDF_Dictionary* pFormDict, for (const auto& it : *pFonts) { const CFX_ByteString& csKey = it.first; - CPDF_Object* pObj = it.second; - if (!pObj) + if (!it.second) continue; - - CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect()); + CPDF_Dictionary* pElement = ToDictionary(it.second->GetDirect()); if (!pElement) continue; if (pElement->GetStringFor("Type") != "Font") @@ -216,16 +216,14 @@ bool FindFont(CPDF_Dictionary* pFormDict, for (const auto& it : *pFonts) { const CFX_ByteString& csKey = it.first; - CPDF_Object* pObj = it.second; - if (!pObj) + if (!it.second) continue; - CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect()); + CPDF_Dictionary* pElement = ToDictionary(it.second->GetDirect()); if (!pElement) continue; if (pElement->GetStringFor("Type") != "Font") continue; - pFont = pDocument->LoadFont(pElement); if (!pFont) continue; @@ -259,23 +257,21 @@ void AddFont(CPDF_Dictionary*& pFormDict, InitDict(pFormDict, pDocument); CPDF_Dictionary* pDR = pFormDict->GetDictFor("DR"); - if (!pDR) { - pDR = new CPDF_Dictionary(pDocument->GetByteStringPool()); - pFormDict->SetFor("DR", pDR); - } + if (!pDR) + pDR = pFormDict->SetNewFor<CPDF_Dictionary>("DR"); + CPDF_Dictionary* pFonts = pDR->GetDictFor("Font"); - if (!pFonts) { - pFonts = new CPDF_Dictionary(pDocument->GetByteStringPool()); - pDR->SetFor("Font", pFonts); - } + if (!pFonts) + pFonts = pDR->SetNewFor<CPDF_Dictionary>("Font"); + if (csNameTag.IsEmpty()) csNameTag = pFont->GetBaseFont(); csNameTag.Remove(' '); csNameTag = CPDF_InterForm::GenerateNewResourceName(pDR, "Font", 4, csNameTag.c_str()); - pFonts->SetReferenceFor(csNameTag, pDocument, - pFont->GetFontDict()->GetObjNum()); + pFonts->SetNewFor<CPDF_Reference>(csNameTag, pDocument, + pFont->GetFontDict()->GetObjNum()); } CPDF_Font* AddNativeFont(CPDF_Dictionary*& pFormDict, @@ -1105,13 +1101,13 @@ CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) { if (pFieldDict->KeyExist("FT")) { CPDF_Object* pFTValue = pFieldDict->GetDirectObjectFor("FT"); if (pFTValue) - pParent->SetFor("FT", pFTValue->Clone().release()); + pParent->SetFor("FT", pFTValue->Clone()); } if (pFieldDict->KeyExist("Ff")) { CPDF_Object* pFfValue = pFieldDict->GetDirectObjectFor("Ff"); if (pFfValue) - pParent->SetFor("Ff", pFfValue->Clone().release()); + pParent->SetFor("Ff", pFfValue->Clone()); } } @@ -1120,9 +1116,9 @@ CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) { if (ToReference(pTObj)) { std::unique_ptr<CPDF_Object> pClone = pTObj->CloneDirectObject(); if (pClone) - pDict->SetFor("T", pClone.release()); + pDict->SetFor("T", std::move(pClone)); else - pDict->SetNameFor("T", ""); + pDict->SetNewFor<CPDF_Name>("T", ""); } m_pFieldTree->SetField(csWName, pField); } @@ -1210,17 +1206,18 @@ CFDF_Document* CPDF_InterForm::ExportToFDF( if (!pdf_path.IsEmpty()) { if (bSimpleFileSpec) { CFX_WideString wsFilePath = CPDF_FileSpec::EncodeFileName(pdf_path); - pMainDict->SetStringFor("F", CFX_ByteString::FromUnicode(wsFilePath)); - pMainDict->SetStringFor("UF", PDF_EncodeText(wsFilePath)); + pMainDict->SetNewFor<CPDF_String>( + "F", CFX_ByteString::FromUnicode(wsFilePath), false); + pMainDict->SetNewFor<CPDF_String>("UF", PDF_EncodeText(wsFilePath), + false); } else { CPDF_FileSpec filespec(pDoc->GetByteStringPool()); filespec.SetFileName(pdf_path); - pMainDict->SetFor("F", filespec.GetObj()); + pMainDict->SetFor("F", pdfium::WrapUnique(filespec.GetObj())); } } - CPDF_Array* pFields = new CPDF_Array; - pMainDict->SetFor("Fields", pFields); + CPDF_Array* pFields = pMainDict->SetNewFor<CPDF_Array>("Fields"); size_t nCount = m_pFieldTree->m_Root.CountFields(); for (size_t i = 0; i < nCount; ++i) { CPDF_FormField* pField = m_pFieldTree->m_Root.GetFieldAtIndex(i); @@ -1238,20 +1235,20 @@ CFDF_Document* CPDF_InterForm::ExportToFDF( CFX_WideString fullname = FPDF_GetFullName(pField->GetFieldDict()); auto pFieldDict = pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()); - pFieldDict->SetFor("T", new CPDF_String(fullname)); + pFieldDict->SetNewFor<CPDF_String>("T", fullname); if (pField->GetType() == CPDF_FormField::CheckBox || pField->GetType() == CPDF_FormField::RadioButton) { CFX_WideString csExport = pField->GetCheckValue(false); CFX_ByteString csBExport = PDF_EncodeText(csExport); CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->m_pDict, "Opt"); if (pOpt) - pFieldDict->SetStringFor("V", csBExport); + pFieldDict->SetNewFor<CPDF_String>("V", csBExport, false); else - pFieldDict->SetNameFor("V", csBExport); + pFieldDict->SetNewFor<CPDF_Name>("V", csBExport); } else { CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V"); if (pV) - pFieldDict->SetFor("V", pV->CloneDirectObject().release()); + pFieldDict->SetFor("V", pV->CloneDirectObject()); } pFields->Add(std::move(pFieldDict)); } @@ -1289,23 +1286,20 @@ void CPDF_InterForm::FDF_ImportField(CPDF_Dictionary* pFieldDict, CFX_WideString csWValue = GetFieldValue(*pFieldDict, m_bsEncoding); int iType = pField->GetFieldType(); if (bNotify && m_pFormNotify) { - int iRet = 0; - if (iType == FIELDTYPE_LISTBOX) - iRet = m_pFormNotify->BeforeSelectionChange(pField, csWValue); - else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) - iRet = m_pFormNotify->BeforeValueChange(pField, csWValue); - - if (iRet < 0) - return; + if (iType == FIELDTYPE_LISTBOX) { + if (m_pFormNotify->BeforeSelectionChange(pField, csWValue) < 0) + return; + } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) { + if (m_pFormNotify->BeforeValueChange(pField, csWValue) < 0) + return; + } } - pField->SetValue(csWValue); CPDF_FormField::Type eType = pField->GetType(); if ((eType == CPDF_FormField::ListBox || eType == CPDF_FormField::ComboBox) && pFieldDict->KeyExist("Opt")) { pField->m_pDict->SetFor( - "Opt", - pFieldDict->GetDirectObjectFor("Opt")->CloneDirectObject().release()); + "Opt", pFieldDict->GetDirectObjectFor("Opt")->CloneDirectObject()); } if (bNotify && m_pFormNotify) { diff --git a/core/fpdfdoc/cpvt_fontmap.cpp b/core/fpdfdoc/cpvt_fontmap.cpp index a47595a6ac..283f60011b 100644 --- a/core/fpdfdoc/cpvt_fontmap.cpp +++ b/core/fpdfdoc/cpvt_fontmap.cpp @@ -9,6 +9,7 @@ #include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_document.h" +#include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfdoc/cpdf_interform.h" CPVT_FontMap::CPVT_FontMap(CPDF_Document* pDoc, @@ -39,8 +40,8 @@ void CPVT_FontMap::GetAnnotSysPDFFont(CPDF_Document* pDoc, CPDF_Dictionary* pFontList = pResDict->GetDictFor("Font"); if (pFontList && !pFontList->KeyExist(sSysFontAlias)) { - pFontList->SetReferenceFor(sSysFontAlias, pDoc, - pPDFFont->GetFontDict()->GetObjNum()); + pFontList->SetNewFor<CPDF_Reference>(sSysFontAlias, pDoc, + pPDFFont->GetFontDict()->GetObjNum()); } pSysFont = pPDFFont; } diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp index 31d2242235..4bb244f29e 100644 --- a/core/fpdfdoc/cpvt_generateap.cpp +++ b/core/fpdfdoc/cpvt_generateap.cpp @@ -11,10 +11,15 @@ #include <utility> #include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/parser/cpdf_boolean.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_reference.h" #include "core/fpdfapi/parser/cpdf_simple_parser.h" #include "core/fpdfapi/parser/cpdf_stream.h" +#include "core/fpdfapi/parser/cpdf_string.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "core/fpdfdoc/cpdf_annot.h" #include "core/fpdfdoc/cpdf_formfield.h" @@ -62,11 +67,12 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, CPDF_Dictionary* pFontDict = pDRFontDict->GetDictFor(sFontName.Mid(1)); if (!pFontDict) { pFontDict = pDoc->NewIndirect<CPDF_Dictionary>(); - pFontDict->SetNameFor("Type", "Font"); - pFontDict->SetNameFor("Subtype", "Type1"); - pFontDict->SetNameFor("BaseFont", "Helvetica"); - pFontDict->SetNameFor("Encoding", "WinAnsiEncoding"); - pDRFontDict->SetReferenceFor(sFontName.Mid(1), pDoc, pFontDict); + pFontDict->SetNewFor<CPDF_Name>("Type", "Font"); + pFontDict->SetNewFor<CPDF_Name>("Subtype", "Type1"); + pFontDict->SetNewFor<CPDF_Name>("BaseFont", "Helvetica"); + pFontDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding"); + pDRFontDict->SetNewFor<CPDF_Reference>(sFontName.Mid(1), pDoc, + pFontDict->GetObjNum()); } CPDF_Font* pDefFont = pDoc->LoadFont(pFontDict); if (!pDefFont) @@ -163,18 +169,15 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, CFX_FloatRect(rcBBox.left + fBorderWidth, rcBBox.bottom + fBorderWidth, rcBBox.right - fBorderWidth, rcBBox.top - fBorderWidth); rcBody.Normalize(); + CPDF_Dictionary* pAPDict = pAnnotDict->GetDictFor("AP"); - if (!pAPDict) { - auto pNewAPDict = - pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()); - // Ownership passes to |pAnnotDict|. - pAPDict = pNewAPDict.release(); - pAnnotDict->SetFor("AP", pAPDict); - } + if (!pAPDict) + pAPDict = pAnnotDict->SetNewFor<CPDF_Dictionary>("AP"); + CPDF_Stream* pNormalStream = pAPDict->GetStreamFor("N"); if (!pNormalStream) { pNormalStream = pDoc->NewIndirect<CPDF_Stream>(); - pAPDict->SetReferenceFor("N", pDoc, pNormalStream); + pAPDict->SetNewFor<CPDF_Reference>("N", pDoc, pNormalStream->GetObjNum()); } CPDF_Dictionary* pStreamDict = pNormalStream->GetDict(); if (pStreamDict) { @@ -183,18 +186,14 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources"); if (pStreamResList) { CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font"); - if (!pStreamResFontList) { - auto pNewStreamResFontList = - pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()); - // Ownership passes to |pStreamResList|. - pStreamResFontList = pNewStreamResFontList.release(); - pStreamResList->SetFor("Font", pStreamResFontList); + if (!pStreamResFontList) + pStreamResFontList = pStreamResList->SetNewFor<CPDF_Dictionary>("Font"); + if (!pStreamResFontList->KeyExist(sFontName)) { + pStreamResFontList->SetNewFor<CPDF_Reference>(sFontName, pDoc, + pFontDict->GetObjNum()); } - if (!pStreamResFontList->KeyExist(sFontName)) - pStreamResFontList->SetReferenceFor(sFontName, pDoc, pFontDict); } else { - pStreamDict->SetFor("Resources", - pFormDict->GetDictFor("DR")->Clone().release()); + pStreamDict->SetFor("Resources", pFormDict->GetDictFor("DR")->Clone()); pStreamResList = pStreamDict->GetDictFor("Resources"); } } @@ -438,17 +437,15 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font"); if (!pStreamResFontList) { - auto pNewStreamResFontList = - pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()); - // Ownership passes to |pStreamResList|. - pStreamResFontList = pNewStreamResFontList.release(); - pStreamResList->SetFor("Font", pStreamResFontList); + pStreamResFontList = + pStreamResList->SetNewFor<CPDF_Dictionary>("Font"); + } + if (!pStreamResFontList->KeyExist(sFontName)) { + pStreamResFontList->SetNewFor<CPDF_Reference>(sFontName, pDoc, + pFontDict->GetObjNum()); } - if (!pStreamResFontList->KeyExist(sFontName)) - pStreamResFontList->SetReferenceFor(sFontName, pDoc, pFontDict); } else { - pStreamDict->SetFor("Resources", - pFormDict->GetDictFor("DR")->Clone().release()); + pStreamDict->SetFor("Resources", pFormDict->GetDictFor("DR")->Clone()); pStreamResList = pStreamDict->GetDictFor("Resources"); } } @@ -554,18 +551,18 @@ std::unique_ptr<CPDF_Dictionary> GenerateExtGStateDict( const CFX_ByteString& sBlendMode) { auto pGSDict = pdfium::MakeUnique<CPDF_Dictionary>(pAnnotDict.GetByteStringPool()); - pGSDict->SetStringFor("Type", "ExtGState"); + pGSDict->SetNewFor<CPDF_String>("Type", "ExtGState", false); FX_FLOAT fOpacity = pAnnotDict.KeyExist("CA") ? pAnnotDict.GetNumberFor("CA") : 1; - pGSDict->SetNumberFor("CA", fOpacity); - pGSDict->SetNumberFor("ca", fOpacity); - pGSDict->SetBooleanFor("AIS", false); - pGSDict->SetStringFor("BM", sBlendMode); + pGSDict->SetNewFor<CPDF_Number>("CA", fOpacity); + pGSDict->SetNewFor<CPDF_Number>("ca", fOpacity); + pGSDict->SetNewFor<CPDF_Boolean>("AIS", false); + pGSDict->SetNewFor<CPDF_String>("BM", sBlendMode, false); auto pExtGStateDict = pdfium::MakeUnique<CPDF_Dictionary>(pAnnotDict.GetByteStringPool()); - pExtGStateDict->SetFor(sExtGSDictName, pGSDict.release()); + pExtGStateDict->SetFor(sExtGSDictName, std::move(pGSDict)); return pExtGStateDict; } @@ -573,14 +570,15 @@ std::unique_ptr<CPDF_Dictionary> GenerateResourceFontDict( CPDF_Document* pDoc, const CFX_ByteString& sFontDictName) { CPDF_Dictionary* pFontDict = pDoc->NewIndirect<CPDF_Dictionary>(); - pFontDict->SetNameFor("Type", "Font"); - pFontDict->SetNameFor("Subtype", "Type1"); - pFontDict->SetNameFor("BaseFont", "Helvetica"); - pFontDict->SetNameFor("Encoding", "WinAnsiEncoding"); + pFontDict->SetNewFor<CPDF_Name>("Type", "Font"); + pFontDict->SetNewFor<CPDF_Name>("Subtype", "Type1"); + pFontDict->SetNewFor<CPDF_Name>("BaseFont", "Helvetica"); + pFontDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding"); auto pResourceFontDict = pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()); - pResourceFontDict->SetReferenceFor(sFontDictName, pDoc, pFontDict); + pResourceFontDict->SetNewFor<CPDF_Reference>(sFontDictName, pDoc, + pFontDict->GetObjNum()); return pResourceFontDict; } @@ -591,9 +589,9 @@ std::unique_ptr<CPDF_Dictionary> GenerateResourceDict( auto pResourceDict = pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()); if (pExtGStateDict) - pResourceDict->SetFor("ExtGState", pExtGStateDict.release()); + pResourceDict->SetFor("ExtGState", std::move(pExtGStateDict)); if (pResourceFontDict) - pResourceDict->SetFor("Font", pResourceFontDict.release()); + pResourceDict->SetFor("Font", std::move(pResourceFontDict)); return pResourceDict; } @@ -605,20 +603,19 @@ void GenerateAndSetAPDict(CPDF_Document* pDoc, CPDF_Stream* pNormalStream = pDoc->NewIndirect<CPDF_Stream>(); pNormalStream->SetData(sAppStream.GetBuffer(), sAppStream.GetSize()); - auto pAPDict = pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()); - pAPDict->SetReferenceFor("N", pDoc, pNormalStream); - pAnnotDict->SetFor("AP", pAPDict.release()); + CPDF_Dictionary* pAPDict = pAnnotDict->SetNewFor<CPDF_Dictionary>("AP"); + pAPDict->SetNewFor<CPDF_Reference>("N", pDoc, pNormalStream->GetObjNum()); CPDF_Dictionary* pStreamDict = pNormalStream->GetDict(); - pStreamDict->SetIntegerFor("FormType", 1); - pStreamDict->SetStringFor("Subtype", "Form"); + pStreamDict->SetNewFor<CPDF_Number>("FormType", 1); + pStreamDict->SetNewFor<CPDF_String>("Subtype", "Form", false); pStreamDict->SetMatrixFor("Matrix", CFX_Matrix()); CFX_FloatRect rect = bIsTextMarkupAnnotation ? CPDF_Annot::RectFromQuadPoints(pAnnotDict) : pAnnotDict->GetRectFor("Rect"); pStreamDict->SetRectFor("BBox", rect); - pStreamDict->SetFor("Resources", pResourceDict.release()); + pStreamDict->SetFor("Resources", std::move(pResourceDict)); } CFX_ByteString GetPaintOperatorString(bool bIsStrokeRect, bool bIsFillRect) { @@ -693,7 +690,6 @@ bool FPDF_GenerateAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) { CPDF_Object* pFieldFlagsObj = FPDF_GetFieldAttr(pAnnotDict, "Ff"); uint32_t flags = pFieldFlagsObj ? pFieldFlagsObj->GetInteger() : 0; - if (field_type == "Ch") { return (flags & (1 << 17)) ? CPVT_GenerateAP::GenerateComboBoxAP(pDoc, pAnnotDict) @@ -705,7 +701,8 @@ bool FPDF_GenerateAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) { if (!pAnnotDict->KeyExist("AS")) { if (CPDF_Dictionary* pParentDict = pAnnotDict->GetDictFor("Parent")) { if (pParentDict->KeyExist("AS")) { - pAnnotDict->SetStringFor("AS", pParentDict->GetStringFor("AS")); + pAnnotDict->SetNewFor<CPDF_String>( + "AS", pParentDict->GetStringFor("AS"), false); } } } diff --git a/core/fxge/dib/fx_dib_engine_unittest.cpp b/core/fxge/dib/fx_dib_engine_unittest.cpp index 57e829e9d2..faacebd5fc 100644 --- a/core/fxge/dib/fx_dib_engine_unittest.cpp +++ b/core/fxge/dib/fx_dib_engine_unittest.cpp @@ -18,8 +18,8 @@ TEST(CStretchEngine, OverflowInCtor) { FX_RECT clip_rect; std::unique_ptr<CPDF_Dictionary> dict_obj = pdfium::MakeUnique<CPDF_Dictionary>(); - dict_obj->SetFor("Width", new CPDF_Number(71000)); - dict_obj->SetFor("Height", new CPDF_Number(12500)); + dict_obj->SetNewFor<CPDF_Number>("Width", 71000); + dict_obj->SetNewFor<CPDF_Number>("Height", 12500); std::unique_ptr<CPDF_Stream> stream = pdfium::MakeUnique<CPDF_Stream>(nullptr, 0, dict_obj.release()); CPDF_DIBSource dib_source; diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.cpp b/fpdfsdk/cpdfsdk_annothandlermgr.cpp index 51ce88e21f..898b9ccc0f 100644 --- a/fpdfsdk/cpdfsdk_annothandlermgr.cpp +++ b/fpdfsdk/cpdfsdk_annothandlermgr.cpp @@ -6,6 +6,8 @@ #include "fpdfsdk/cpdfsdk_annothandlermgr.h" +#include "core/fpdfapi/parser/cpdf_number.h" +#include "core/fpdfapi/parser/cpdf_string.h" #include "core/fpdfdoc/cpdf_annot.h" #include "fpdfsdk/cba_annotiterator.h" #include "fpdfsdk/cpdfsdk_annot.h" @@ -62,8 +64,9 @@ void CPDFSDK_AnnotHandlerMgr::Annot_OnCreate(CPDFSDK_Annot* pAnnot) { CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot(); CPDFSDK_DateTime curTime; - pPDFAnnot->GetAnnotDict()->SetStringFor("M", curTime.ToPDFDateTimeString()); - pPDFAnnot->GetAnnotDict()->SetNumberFor("F", 0); + pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_String>( + "M", curTime.ToPDFDateTimeString(), false); + pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("F", 0); } void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot) { diff --git a/fpdfsdk/cpdfsdk_baannot.cpp b/fpdfsdk/cpdfsdk_baannot.cpp index ee4b55d290..9fb1e88a84 100644 --- a/fpdfsdk/cpdfsdk_baannot.cpp +++ b/fpdfsdk/cpdfsdk_baannot.cpp @@ -6,10 +6,15 @@ #include "fpdfsdk/cpdfsdk_baannot.h" +#include <algorithm> + #include "core/fpdfapi/parser/cpdf_array.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_reference.h" #include "core/fpdfapi/parser/cpdf_stream.h" +#include "core/fpdfapi/parser/cpdf_string.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "fpdfsdk/cpdfsdk_datetime.h" #include "fpdfsdk/cpdfsdk_pageview.h" @@ -89,11 +94,12 @@ void CPDFSDK_BAAnnot::ClearCachedAP() { } void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents) { - if (sContents.IsEmpty()) + if (sContents.IsEmpty()) { m_pAnnot->GetAnnotDict()->RemoveFor("Contents"); - else - m_pAnnot->GetAnnotDict()->SetStringFor("Contents", - PDF_EncodeText(sContents)); + } else { + m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>( + "Contents", PDF_EncodeText(sContents), false); + } } CFX_WideString CPDFSDK_BAAnnot::GetContents() const { @@ -101,10 +107,12 @@ CFX_WideString CPDFSDK_BAAnnot::GetContents() const { } void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName) { - if (sName.IsEmpty()) + if (sName.IsEmpty()) { m_pAnnot->GetAnnotDict()->RemoveFor("NM"); - else - m_pAnnot->GetAnnotDict()->SetStringFor("NM", PDF_EncodeText(sName)); + } else { + m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>( + "NM", PDF_EncodeText(sName), false); + } } CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const { @@ -114,25 +122,23 @@ CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const { void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st) { CPDFSDK_DateTime dt(st); CFX_ByteString str = dt.ToPDFDateTimeString(); - if (str.IsEmpty()) m_pAnnot->GetAnnotDict()->RemoveFor("M"); else - m_pAnnot->GetAnnotDict()->SetStringFor("M", str); + m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>("M", str, false); } FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const { FX_SYSTEMTIME systime; CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetStringFor("M"); - CPDFSDK_DateTime dt(str); dt.ToSystemTime(systime); - return systime; } void CPDFSDK_BAAnnot::SetFlags(uint32_t nFlags) { - m_pAnnot->GetAnnotDict()->SetIntegerFor("F", nFlags); + m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("F", + static_cast<int>(nFlags)); } uint32_t CPDFSDK_BAAnnot::GetFlags() const { @@ -143,7 +149,7 @@ void CPDFSDK_BAAnnot::SetAppState(const CFX_ByteString& str) { if (str.IsEmpty()) m_pAnnot->GetAnnotDict()->RemoveFor("AS"); else - m_pAnnot->GetAnnotDict()->SetStringFor("AS", str); + m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>("AS", str, false); } CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const { @@ -151,7 +157,7 @@ CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const { } void CPDFSDK_BAAnnot::SetStructParent(int key) { - m_pAnnot->GetAnnotDict()->SetIntegerFor("StructParent", key); + m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("StructParent", key); } int CPDFSDK_BAAnnot::GetStructParent() const { @@ -165,12 +171,10 @@ void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) { pBorder->SetNewAt<CPDF_Number>(2, nWidth); } else { CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS"); - if (!pBSDict) { - pBSDict = - new CPDF_Dictionary(m_pAnnot->GetDocument()->GetByteStringPool()); - m_pAnnot->GetAnnotDict()->SetFor("BS", pBSDict); - } - pBSDict->SetIntegerFor("W", nWidth); + if (!pBSDict) + pBSDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS"); + + pBSDict->SetNewFor<CPDF_Number>("W", nWidth); } } @@ -186,26 +190,24 @@ int CPDFSDK_BAAnnot::GetBorderWidth() const { void CPDFSDK_BAAnnot::SetBorderStyle(BorderStyle nStyle) { CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS"); - if (!pBSDict) { - pBSDict = new CPDF_Dictionary(m_pAnnot->GetDocument()->GetByteStringPool()); - m_pAnnot->GetAnnotDict()->SetFor("BS", pBSDict); - } + if (!pBSDict) + pBSDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS"); switch (nStyle) { case BorderStyle::SOLID: - pBSDict->SetNameFor("S", "S"); + pBSDict->SetNewFor<CPDF_Name>("S", "S"); break; case BorderStyle::DASH: - pBSDict->SetNameFor("S", "D"); + pBSDict->SetNewFor<CPDF_Name>("S", "D"); break; case BorderStyle::BEVELED: - pBSDict->SetNameFor("S", "B"); + pBSDict->SetNewFor<CPDF_Name>("S", "B"); break; case BorderStyle::INSET: - pBSDict->SetNameFor("S", "I"); + pBSDict->SetNewFor<CPDF_Name>("S", "I"); break; case BorderStyle::UNDERLINE: - pBSDict->SetNameFor("S", "U"); + pBSDict->SetNewFor<CPDF_Name>("S", "U"); break; default: break; @@ -241,14 +243,13 @@ BorderStyle CPDFSDK_BAAnnot::GetBorderStyle() const { } void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) { - CPDF_Array* pArray = new CPDF_Array; + CPDF_Array* pArray = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Array>("C"); pArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(FXSYS_GetRValue(color)) / 255.0f); pArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(FXSYS_GetGValue(color)) / 255.0f); pArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(FXSYS_GetBValue(color)) / 255.0f); - m_pAnnot->GetAnnotDict()->SetFor("C", pArray); } void CPDFSDK_BAAnnot::RemoveColor() { @@ -297,10 +298,8 @@ void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType, const CFX_ByteString& sContents, const CFX_ByteString& sAPState) { CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP"); - if (!pAPDict) { - pAPDict = new CPDF_Dictionary(m_pAnnot->GetDocument()->GetByteStringPool()); - m_pAnnot->GetAnnotDict()->SetFor("AP", pAPDict); - } + if (!pAPDict) + pAPDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("AP"); CPDF_Stream* pStream = nullptr; CPDF_Dictionary* pParentDict = nullptr; @@ -309,11 +308,9 @@ void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType, pStream = pAPDict->GetStreamFor(sAPType); } else { CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictFor(sAPType); - if (!pAPTypeDict) { - pAPTypeDict = - new CPDF_Dictionary(m_pAnnot->GetDocument()->GetByteStringPool()); - pAPDict->SetFor(sAPType, pAPTypeDict); - } + if (!pAPTypeDict) + pAPTypeDict = pAPDict->SetNewFor<CPDF_Dictionary>(sAPType); + pParentDict = pAPTypeDict; pStream = pAPTypeDict->GetStreamFor(sAPState); } @@ -321,16 +318,16 @@ void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType, if (!pStream) { CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); pStream = pDoc->NewIndirect<CPDF_Stream>(); - pParentDict->SetReferenceFor(sAPType, pDoc, pStream); + pParentDict->SetNewFor<CPDF_Reference>(sAPType, pDoc, pStream->GetObjNum()); } CPDF_Dictionary* pStreamDict = pStream->GetDict(); if (!pStreamDict) { pStreamDict = new CPDF_Dictionary(m_pAnnot->GetDocument()->GetByteStringPool()); - pStreamDict->SetNameFor("Type", "XObject"); - pStreamDict->SetNameFor("Subtype", "Form"); - pStreamDict->SetIntegerFor("FormType", 1); + pStreamDict->SetNewFor<CPDF_Name>("Type", "XObject"); + pStreamDict->SetNewFor<CPDF_Name>("Subtype", "Form"); + pStreamDict->SetNewFor<CPDF_Number>("FormType", 1); pStream->InitStream(nullptr, 0, pStreamDict); } @@ -358,7 +355,8 @@ void CPDFSDK_BAAnnot::SetAction(const CPDF_Action& action) { CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); if (pDict->IsInline()) pDict = pDoc->AddIndirectObject(pDict->Clone())->AsDictionary(); - m_pAnnot->GetAnnotDict()->SetReferenceFor("A", pDoc, pDict); + m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Reference>("A", pDoc, + pDict->GetObjNum()); } } @@ -372,7 +370,7 @@ CPDF_AAction CPDFSDK_BAAnnot::GetAAction() const { void CPDFSDK_BAAnnot::SetAAction(const CPDF_AAction& aa) { if (aa.GetDict() != m_pAnnot->GetAnnotDict()->GetDictFor("AA")) - m_pAnnot->GetAnnotDict()->SetFor("AA", aa.GetDict()); + m_pAnnot->GetAnnotDict()->SetFor("AA", pdfium::WrapUnique(aa.GetDict())); } void CPDFSDK_BAAnnot::RemoveAAction() { @@ -381,7 +379,6 @@ void CPDFSDK_BAAnnot::RemoveAAction() { CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT) { CPDF_AAction AAction = GetAAction(); - if (AAction.ActionExist(eAAT)) return AAction.GetAction(eAAT); diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp index b1c3379ac9..108690665c 100644 --- a/fpdfsdk/cpdfsdk_widget.cpp +++ b/fpdfsdk/cpdfsdk_widget.cpp @@ -8,9 +8,12 @@ #include <memory> +#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_reference.h" #include "core/fpdfapi/parser/cpdf_stream.h" +#include "core/fpdfapi/parser/cpdf_string.h" #include "core/fpdfdoc/cpdf_defaultappearance.h" #include "core/fpdfdoc/cpdf_formcontrol.h" #include "core/fpdfdoc/cpdf_formfield.h" @@ -966,21 +969,21 @@ void CPDFSDK_Widget::ResetAppearance_PushButton() { if (pNormalIcon) { if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) { if (pImageDict->GetStringFor("Name").IsEmpty()) - pImageDict->SetStringFor("Name", "ImgA"); + pImageDict->SetNewFor<CPDF_String>("Name", "ImgA", false); } } if (pRolloverIcon) { if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) { if (pImageDict->GetStringFor("Name").IsEmpty()) - pImageDict->SetStringFor("Name", "ImgB"); + pImageDict->SetNewFor<CPDF_String>("Name", "ImgB", false); } } if (pDownIcon) { if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) { if (pImageDict->GetStringFor("Name").IsEmpty()) - pImageDict->SetStringFor("Name", "ImgC"); + pImageDict->SetNewFor<CPDF_String>("Name", "ImgC", false); } } @@ -1804,14 +1807,12 @@ void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType, CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources"); - if (!pStreamResList) { - pStreamResList = new CPDF_Dictionary(pDoc->GetByteStringPool()); - pStreamDict->SetFor("Resources", pStreamResList); - } + if (!pStreamResList) + pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources"); - CPDF_Dictionary* pXObject = new CPDF_Dictionary(pDoc->GetByteStringPool()); - pXObject->SetReferenceFor(sImageAlias, pDoc, pImage->GetObjNum()); - pStreamResList->SetFor("XObject", pXObject); + CPDF_Dictionary* pXObject = + pStreamResList->SetNewFor<CPDF_Dictionary>("XObject"); + pXObject->SetNewFor<CPDF_Reference>(sImageAlias, pDoc, pImage->GetObjNum()); } void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) { diff --git a/fpdfsdk/formfiller/cba_fontmap.cpp b/fpdfsdk/formfiller/cba_fontmap.cpp index fd9304befc..83e45791e2 100644 --- a/fpdfsdk/formfiller/cba_fontmap.cpp +++ b/fpdfsdk/formfiller/cba_fontmap.cpp @@ -9,6 +9,7 @@ #include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/page/cpdf_page.h" #include "core/fpdfapi/parser/cpdf_document.h" +#include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfapi/parser/cpdf_simple_parser.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" @@ -119,11 +120,10 @@ CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict, CPDF_Font* pFind = nullptr; for (const auto& it : *pFonts) { const CFX_ByteString& csKey = it.first; - CPDF_Object* pObj = it.second; - if (!pObj) + if (!it.second) continue; - CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect()); + CPDF_Dictionary* pElement = ToDictionary(it.second->GetDirect()); if (!pElement) continue; if (pElement->GetStringFor("Type") != "Font") @@ -154,10 +154,8 @@ void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont, return; CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictFor("AP"); - if (!pAPDict) { - pAPDict = new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - m_pAnnotDict->SetFor("AP", pAPDict); - } + if (!pAPDict) + pAPDict = m_pAnnotDict->SetNewFor<CPDF_Dictionary>("AP"); // to avoid checkbox and radiobutton CPDF_Object* pObject = pAPDict->GetObjectFor(m_sAPType); @@ -167,7 +165,8 @@ void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont, CPDF_Stream* pStream = pAPDict->GetStreamFor(m_sAPType); if (!pStream) { pStream = m_pDocument->NewIndirect<CPDF_Stream>(); - pAPDict->SetReferenceFor(m_sAPType, m_pDocument, pStream); + pAPDict->SetNewFor<CPDF_Reference>(m_sAPType, m_pDocument, + pStream->GetObjNum()); } CPDF_Dictionary* pStreamDict = pStream->GetDict(); @@ -178,18 +177,17 @@ void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont, if (pStreamDict) { CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources"); - if (!pStreamResList) { - pStreamResList = new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - pStreamDict->SetFor("Resources", pStreamResList); - } + if (!pStreamResList) + pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources"); CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font"); if (!pStreamResFontList) { pStreamResFontList = m_pDocument->NewIndirect<CPDF_Dictionary>(); - pStreamResList->SetReferenceFor("Font", m_pDocument, pStreamResFontList); + pStreamResList->SetNewFor<CPDF_Reference>( + "Font", m_pDocument, pStreamResFontList->GetObjNum()); } if (!pStreamResFontList->KeyExist(sAlias)) { - pStreamResFontList->SetReferenceFor(sAlias, m_pDocument, - pFont->GetFontDict()->GetObjNum()); + pStreamResFontList->SetNewFor<CPDF_Reference>( + sAlias, m_pDocument, pFont->GetFontDict()->GetObjNum()); } } } diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp index cb0a625e23..ccbb7b8765 100644 --- a/fpdfsdk/fpdf_flatten.cpp +++ b/fpdfsdk/fpdf_flatten.cpp @@ -7,11 +7,15 @@ #include "public/fpdf_flatten.h" #include <algorithm> +#include <memory> +#include <utility> +#include <vector> #include "core/fpdfapi/page/cpdf_page.h" #include "core/fpdfapi/page/cpdf_pageobject.h" #include "core/fpdfapi/parser/cpdf_array.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_reference.h" #include "core/fpdfapi/parser/cpdf_stream.h" @@ -190,8 +194,8 @@ void SetPageContents(const CFX_ByteString& key, pContentsArray = pPage->GetArrayFor("Contents"); if (!pContentsArray) { if (!key.IsEmpty()) { - pPage->SetReferenceFor("Contents", pDocument, - NewIndirectContentsStream(key, pDocument)); + pPage->SetNewFor<CPDF_Reference>( + "Contents", pDocument, NewIndirectContentsStream(key, pDocument)); } return; } @@ -208,7 +212,8 @@ void SetPageContents(const CFX_ByteString& key, pContentsStream->SetData(sStream.raw_str(), sStream.GetLength()); pContentsArray->AddNew<CPDF_Reference>(pDocument, pContentsStream->GetObjNum()); - pPage->SetReferenceFor("Contents", pDocument, pContentsArray); + pPage->SetNewFor<CPDF_Reference>("Contents", pDocument, + pContentsArray->GetObjNum()); } if (!key.IsEmpty()) { pContentsArray->AddNew<CPDF_Reference>( @@ -271,38 +276,32 @@ DLLEXPORT int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag) { rcOriginalCB = rcOriginalMB; if (!rcOriginalMB.IsEmpty()) { - CPDF_Array* pMediaBox = new CPDF_Array(); + CPDF_Array* pMediaBox = pPageDict->SetNewFor<CPDF_Array>("MediaBox"); pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.left); pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.bottom); pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.right); pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.top); - pPageDict->SetFor("MediaBox", pMediaBox); } if (!rcOriginalCB.IsEmpty()) { - CPDF_Array* pCropBox = new CPDF_Array(); + CPDF_Array* pCropBox = pPageDict->SetNewFor<CPDF_Array>("ArtBox"); pCropBox->AddNew<CPDF_Number>(rcOriginalCB.left); pCropBox->AddNew<CPDF_Number>(rcOriginalCB.bottom); pCropBox->AddNew<CPDF_Number>(rcOriginalCB.right); pCropBox->AddNew<CPDF_Number>(rcOriginalCB.top); - pPageDict->SetFor("ArtBox", pCropBox); } CPDF_Dictionary* pRes = pPageDict->GetDictFor("Resources"); - if (!pRes) { - pRes = new CPDF_Dictionary(pDocument->GetByteStringPool()); - pPageDict->SetFor("Resources", pRes); - } + if (!pRes) + pRes = pPageDict->SetNewFor<CPDF_Dictionary>("Resources"); CPDF_Stream* pNewXObject = pDocument->NewIndirect<CPDF_Stream>( nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool())); uint32_t dwObjNum = pNewXObject->GetObjNum(); CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject"); - if (!pPageXObject) { - pPageXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); - pRes->SetFor("XObject", pPageXObject); - } + if (!pPageXObject) + pPageXObject = pRes->SetNewFor<CPDF_Dictionary>("XObject"); CFX_ByteString key = ""; int nStreams = pdfium::CollectionSize<int>(ObjectArray); @@ -320,14 +319,13 @@ DLLEXPORT int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag) { CPDF_Dictionary* pNewXORes = nullptr; if (!key.IsEmpty()) { - pPageXObject->SetReferenceFor(key, pDocument, dwObjNum); + pPageXObject->SetNewFor<CPDF_Reference>(key, pDocument, dwObjNum); CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict(); - pNewXORes = new CPDF_Dictionary(pDocument->GetByteStringPool()); - pNewOXbjectDic->SetFor("Resources", pNewXORes); - pNewOXbjectDic->SetNameFor("Type", "XObject"); - pNewOXbjectDic->SetNameFor("Subtype", "Form"); - pNewOXbjectDic->SetIntegerFor("FormType", 1); - pNewOXbjectDic->SetNameFor("Name", "FRM"); + pNewXORes = pNewOXbjectDic->SetNewFor<CPDF_Dictionary>("Resources"); + pNewOXbjectDic->SetNewFor<CPDF_Name>("Type", "XObject"); + pNewOXbjectDic->SetNewFor<CPDF_Name>("Subtype", "Form"); + pNewOXbjectDic->SetNewFor<CPDF_Number>("FormType", 1); + pNewOXbjectDic->SetNewFor<CPDF_Name>("Name", "FRM"); CFX_FloatRect rcBBox = pPageDict->GetRectFor("ArtBox"); pNewOXbjectDic->SetRectFor("BBox", rcBBox); } @@ -356,7 +354,7 @@ DLLEXPORT int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag) { } else { auto it = pAPDic->begin(); if (it != pAPDic->end()) { - CPDF_Object* pFirstObj = it->second; + CPDF_Object* pFirstObj = it->second.get(); if (pFirstObj) { if (pFirstObj->IsReference()) pFirstObj = pFirstObj->GetDirect(); @@ -389,19 +387,18 @@ DLLEXPORT int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag) { CPDF_Dictionary* pObjDic = pObj->GetDict(); if (pObjDic) { - pObjDic->SetNameFor("Type", "XObject"); - pObjDic->SetNameFor("Subtype", "Form"); + pObjDic->SetNewFor<CPDF_Name>("Type", "XObject"); + pObjDic->SetNewFor<CPDF_Name>("Subtype", "Form"); } CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject"); - if (!pXObject) { - pXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); - pNewXORes->SetFor("XObject", pXObject); - } + if (!pXObject) + pXObject = pNewXORes->SetNewFor<CPDF_Dictionary>("XObject"); CFX_ByteString sFormName; sFormName.Format("F%d", i); - pXObject->SetReferenceFor(sFormName, pDocument, pObj->GetObjNum()); + pXObject->SetNewFor<CPDF_Reference>(sFormName, pDocument, + pObj->GetObjNum()); CPDF_StreamAcc acc; acc.LoadAllData(pNewXObject); diff --git a/fpdfsdk/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp index beaa6c4d98..b1e8da06b9 100644 --- a/fpdfsdk/fpdf_transformpage.cpp +++ b/fpdfsdk/fpdf_transformpage.cpp @@ -26,12 +26,11 @@ void SetBoundingBox(CPDF_Page* page, float bottom, float right, float top) { - CPDF_Array* pBoundingBoxArray = new CPDF_Array; + CPDF_Array* pBoundingBoxArray = page->m_pFormDict->SetNewFor<CPDF_Array>(key); pBoundingBoxArray->AddNew<CPDF_Number>(left); pBoundingBoxArray->AddNew<CPDF_Number>(bottom); pBoundingBoxArray->AddNew<CPDF_Number>(right); pBoundingBoxArray->AddNew<CPDF_Number>(top); - page->m_pFormDict->SetFor(key, pBoundingBoxArray); } bool GetBoundingBox(CPDF_Page* page, @@ -158,7 +157,8 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum()); pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum()); pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum()); - pPageDic->SetReferenceFor("Contents", pDoc, pContentArray); + pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc, + pContentArray->GetObjNum()); } } } @@ -169,7 +169,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, CPDF_Dictionary* pPattenDict = pRes->GetDictFor("Pattern"); if (pPattenDict) { for (const auto& it : *pPattenDict) { - CPDF_Object* pObj = it.second; + CPDF_Object* pObj = it.second.get(); if (pObj->IsReference()) pObj = pObj->GetDirect(); @@ -328,6 +328,7 @@ DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page, CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>(); pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum()); pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum()); - pPageDic->SetReferenceFor("Contents", pDoc, pContentArray); + pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc, + pContentArray->GetObjNum()); } } diff --git a/fpdfsdk/fpdfdoc_unittest.cpp b/fpdfsdk/fpdfdoc_unittest.cpp index d049b4e757..664ce39381 100644 --- a/fpdfsdk/fpdfdoc_unittest.cpp +++ b/fpdfsdk/fpdfdoc_unittest.cpp @@ -105,7 +105,7 @@ TEST_F(PDFDocTest, FindBookmark) { } { // Empty bookmark tree. - m_pRootObj->SetFor("Outlines", new CPDF_Dictionary()); + m_pRootObj->SetNewFor<CPDF_Dictionary>("Outlines"); std::unique_ptr<unsigned short, pdfium::FreeDeleter> title = GetFPDFWideString(L""); EXPECT_EQ(nullptr, FPDFBookmark_Find(m_pDoc.get(), title.get())); @@ -117,27 +117,27 @@ TEST_F(PDFDocTest, FindBookmark) { // Check on a regular bookmark tree. auto bookmarks = CreateDictObjs(3); - bookmarks[1].obj->SetFor("Title", new CPDF_String(L"Chapter 1")); - bookmarks[1].obj->SetFor( - "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num)); - bookmarks[1].obj->SetFor( - "Next", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num)); + bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1"); + bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs, + bookmarks[0].num); + bookmarks[1].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs, + bookmarks[2].num); - bookmarks[2].obj->SetFor("Title", new CPDF_String(L"Chapter 2")); - bookmarks[2].obj->SetFor( - "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num)); - bookmarks[2].obj->SetFor( - "Prev", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num)); + bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2"); + bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs, + bookmarks[0].num); + bookmarks[2].obj->SetNewFor<CPDF_Reference>("Prev", m_pIndirectObjs, + bookmarks[1].num); - 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)); - bookmarks[0].obj->SetFor( - "Last", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num)); + bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines"); + bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2); + bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs, + bookmarks[1].num); + bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs, + bookmarks[2].num); - m_pRootObj->SetFor("Outlines", - new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num)); + m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs, + bookmarks[0].num); // Title with no match. std::unique_ptr<unsigned short, pdfium::FreeDeleter> title = @@ -160,27 +160,27 @@ TEST_F(PDFDocTest, FindBookmark) { // Circular bookmarks in depth. auto bookmarks = CreateDictObjs(3); - bookmarks[1].obj->SetFor("Title", new CPDF_String(L"Chapter 1")); - bookmarks[1].obj->SetFor( - "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num)); - bookmarks[1].obj->SetFor( - "First", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num)); + bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1"); + bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs, + bookmarks[0].num); + bookmarks[1].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs, + bookmarks[2].num); - bookmarks[2].obj->SetFor("Title", new CPDF_String(L"Chapter 2")); - bookmarks[2].obj->SetFor( - "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num)); - bookmarks[2].obj->SetFor( - "First", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num)); + bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2"); + bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs, + bookmarks[1].num); + bookmarks[2].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs, + bookmarks[1].num); - 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)); - bookmarks[0].obj->SetFor( - "Last", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num)); + bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines"); + bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2); + bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs, + bookmarks[1].num); + bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs, + bookmarks[2].num); - m_pRootObj->SetFor("Outlines", - new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num)); + m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs, + bookmarks[0].num); // Title with no match. std::unique_ptr<unsigned short, pdfium::FreeDeleter> title = @@ -195,33 +195,33 @@ TEST_F(PDFDocTest, FindBookmark) { // Circular bookmarks in breadth. auto bookmarks = CreateDictObjs(4); - bookmarks[1].obj->SetFor("Title", new CPDF_String(L"Chapter 1")); - bookmarks[1].obj->SetFor( - "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num)); - bookmarks[1].obj->SetFor( - "Next", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num)); - - bookmarks[2].obj->SetFor("Title", new CPDF_String(L"Chapter 2")); - bookmarks[2].obj->SetFor( - "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num)); - bookmarks[2].obj->SetFor( - "Next", new CPDF_Reference(m_pIndirectObjs, bookmarks[3].num)); - - bookmarks[3].obj->SetFor("Title", new CPDF_String(L"Chapter 3")); - bookmarks[3].obj->SetFor( - "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num)); - bookmarks[3].obj->SetFor( - "Next", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num)); - - 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)); - bookmarks[0].obj->SetFor( - "Last", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num)); - - m_pRootObj->SetFor("Outlines", - new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num)); + bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1"); + bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs, + bookmarks[0].num); + bookmarks[1].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs, + bookmarks[2].num); + + bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2"); + bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs, + bookmarks[0].num); + bookmarks[2].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs, + bookmarks[3].num); + + bookmarks[3].obj->SetNewFor<CPDF_String>("Title", L"Chapter 3"); + bookmarks[3].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs, + bookmarks[0].num); + bookmarks[3].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs, + bookmarks[1].num); + + bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines"); + bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2); + bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs, + bookmarks[1].num); + bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs, + bookmarks[2].num); + + m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs, + bookmarks[0].num); // Title with no match. std::unique_ptr<unsigned short, pdfium::FreeDeleter> title = diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp index 847adac7ec..c864b82145 100644 --- a/fpdfsdk/fpdfeditpage.cpp +++ b/fpdfsdk/fpdfeditpage.cpp @@ -83,11 +83,9 @@ 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(nullptr, DateStr, false)); - } - pInfoDict->SetFor("Creator", new CPDF_String(L"PDFium")); + if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) + pInfoDict->SetNewFor<CPDF_String>("CreationDate", DateStr, false); + pInfoDict->SetNewFor<CPDF_String>("Creator", L"PDFium"); } return FPDFDocumentFromCPDFDocument(pDoc); @@ -111,15 +109,13 @@ DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, if (!pPageDict) return nullptr; - CPDF_Array* pMediaBoxArray = new CPDF_Array; + CPDF_Array* pMediaBoxArray = pPageDict->SetNewFor<CPDF_Array>("MediaBox"); pMediaBoxArray->AddNew<CPDF_Number>(0); pMediaBoxArray->AddNew<CPDF_Number>(0); pMediaBoxArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(width)); pMediaBoxArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(height)); - pPageDict->SetFor("MediaBox", pMediaBoxArray); - pPageDict->SetFor("Rotate", new CPDF_Number(0)); - pPageDict->SetFor("Resources", - new CPDF_Dictionary(pDoc->GetByteStringPool())); + pPageDict->SetNewFor<CPDF_Number>("Rotate", 0); + pPageDict->SetNewFor<CPDF_Dictionary>("Resources"); #ifdef PDF_ENABLE_XFA CPDFXFA_Page* pPage = @@ -296,10 +292,9 @@ DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page, rect.Transform(&matrix); CPDF_Array* pRectArray = pAnnot->GetAnnotDict()->GetArrayFor("Rect"); - if (!pRectArray) { - pRectArray = new CPDF_Array; - pAnnot->GetAnnotDict()->SetFor("Rect", pRectArray); - } + if (!pRectArray) + pRectArray = pAnnot->GetAnnotDict()->SetNewFor<CPDF_Array>("Rect"); + pRectArray->SetNewAt<CPDF_Number>(0, rect.left); pRectArray->SetNewAt<CPDF_Number>(1, rect.bottom); pRectArray->SetNewAt<CPDF_Number>(2, rect.right); @@ -316,5 +311,5 @@ DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate) { CPDF_Dictionary* pDict = pPage->m_pFormDict; rotate %= 4; - pDict->SetFor("Rotate", new CPDF_Number(rotate * 90)); + pDict->SetNewFor<CPDF_Number>("Rotate", rotate * 90); } diff --git a/fpdfsdk/fpdfppo.cpp b/fpdfsdk/fpdfppo.cpp index 915de1ad07..4e06856455 100644 --- a/fpdfsdk/fpdfppo.cpp +++ b/fpdfsdk/fpdfppo.cpp @@ -8,6 +8,7 @@ #include <map> #include <memory> +#include <utility> #include <vector> #include "core/fpdfapi/parser/cpdf_array.h" @@ -64,7 +65,7 @@ bool CopyInheritable(CPDF_Dictionary* pCurPageDict, if (!pInheritable) return false; - pCurPageDict->SetFor(key, pInheritable->Clone().release()); + pCurPageDict->SetFor(key, pInheritable->Clone()); return true; } @@ -158,31 +159,30 @@ bool CPDF_PageOrganizer::PDFDocInit() { if (!pDocInfoDict) return false; - CFX_ByteString producerstr; - producerstr.Format("PDFium"); - pDocInfoDict->SetFor("Producer", - new CPDF_String(nullptr, producerstr, false)); + pDocInfoDict->SetNewFor<CPDF_String>("Producer", "PDFium", false); CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", ""); if (cbRootType.IsEmpty()) - pNewRoot->SetFor("Type", new CPDF_Name(nullptr, "Catalog")); + pNewRoot->SetNewFor<CPDF_Name>("Type", "Catalog"); CPDF_Object* pElement = pNewRoot->GetObjectFor("Pages"); CPDF_Dictionary* pNewPages = pElement ? ToDictionary(pElement->GetDirect()) : nullptr; if (!pNewPages) { pNewPages = m_pDestPDFDoc->NewIndirect<CPDF_Dictionary>(); - pNewRoot->SetReferenceFor("Pages", m_pDestPDFDoc, pNewPages); + pNewRoot->SetNewFor<CPDF_Reference>("Pages", m_pDestPDFDoc, + pNewPages->GetObjNum()); } CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", ""); if (cbPageType.IsEmpty()) - pNewPages->SetFor("Type", new CPDF_Name(nullptr, "Pages")); + pNewPages->SetNewFor<CPDF_Name>("Type", "Pages"); if (!pNewPages->GetArrayFor("Kids")) { - pNewPages->SetIntegerFor("Count", 0); - pNewPages->SetReferenceFor("Kids", m_pDestPDFDoc, - m_pDestPDFDoc->NewIndirect<CPDF_Array>()); + pNewPages->SetNewFor<CPDF_Number>("Count", 0); + pNewPages->SetNewFor<CPDF_Reference>( + "Kids", m_pDestPDFDoc, + m_pDestPDFDoc->NewIndirect<CPDF_Array>()->GetObjNum()); } return true; @@ -202,11 +202,11 @@ bool CPDF_PageOrganizer::ExportPage(const std::vector<uint16_t>& pageNums, // Clone the page dictionary for (const auto& it : *pSrcPageDict) { const CFX_ByteString& cbSrcKeyStr = it.first; - CPDF_Object* pObj = it.second; if (cbSrcKeyStr == "Type" || cbSrcKeyStr == "Parent") continue; - pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone().release()); + CPDF_Object* pObj = it.second.get(); + pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone()); } // inheritable item @@ -217,15 +217,14 @@ bool CPDF_PageOrganizer::ExportPage(const std::vector<uint16_t>& pageNums, CPDF_Object* pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); if (pInheritable) { - pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release()); + pCurPageDict->SetFor("MediaBox", pInheritable->Clone()); } else { // Make the default size to be letter size (8.5'x11') - CPDF_Array* pArray = new CPDF_Array; + CPDF_Array* pArray = pCurPageDict->SetNewFor<CPDF_Array>("MediaBox"); pArray->AddNew<CPDF_Number>(0); pArray->AddNew<CPDF_Number>(0); pArray->AddNew<CPDF_Number>(612); pArray->AddNew<CPDF_Number>(792); - pCurPageDict->SetFor("MediaBox", pArray); } } @@ -265,7 +264,7 @@ bool CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj, auto it = pDict->begin(); while (it != pDict->end()) { const CFX_ByteString& key = it->first; - CPDF_Object* pNextObj = it->second; + CPDF_Object* pNextObj = it->second.get(); ++it; if (key == "Parent" || key == "Prev" || key == "First") continue; @@ -386,7 +385,6 @@ DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc, if (!pDstDict) return false; - pDstDict->SetFor("ViewerPreferences", - pSrcDict->CloneDirectObject().release()); + pDstDict->SetFor("ViewerPreferences", pSrcDict->CloneDirectObject()); return true; } diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp index 334c14cd45..d5f9a0e810 100644 --- a/fpdfsdk/fpdfview.cpp +++ b/fpdfsdk/fpdfview.cpp @@ -1082,7 +1082,7 @@ DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDest(FPDF_DOCUMENT document, int i = 0; for (const auto& it : *pDest) { bsName = it.first; - pDestObj = it.second; + pDestObj = it.second.get(); if (!pDestObj) continue; if (i == index) diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp index 26227c068e..9bb1418379 100644 --- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp +++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp @@ -6,6 +6,8 @@ #include "fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h" +#include <memory> + #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_stream_acc.h" #include "core/fpdfapi/parser/cpdf_string.h" @@ -398,7 +400,7 @@ void CPDFXFA_DocEnvironment::SetTitle(CXFA_FFDoc* hDoc, return; if (CPDF_Dictionary* pInfoDict = m_pContext->GetPDFDoc()->GetInfo()) - pInfoDict->SetFor("Title", new CPDF_String(wsTitle)); + pInfoDict->SetNewFor<CPDF_String>("Title", wsTitle); } void CPDFXFA_DocEnvironment::ExportData(CXFA_FFDoc* hDoc, diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp index 54761a2647..29f9764806 100644 --- a/fpdfsdk/javascript/Document.cpp +++ b/fpdfsdk/javascript/Document.cpp @@ -13,6 +13,7 @@ #include "core/fpdfapi/page/cpdf_page.h" #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_document.h" +#include "core/fpdfapi/parser/cpdf_string.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "core/fpdfdoc/cpdf_interform.h" #include "core/fpdfdoc/cpdf_nametree.h" @@ -809,7 +810,7 @@ bool Document::info(IJS_Context* cc, // It's to be compatible to non-standard info dictionary. for (const auto& it : *pDictionary) { const CFX_ByteString& bsKey = it.first; - CPDF_Object* pValueObj = it.second; + CPDF_Object* pValueObj = it.second.get(); CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey.AsStringC()); if (pValueObj->IsString() || pValueObj->IsName()) { pRuntime->PutObjectString(pObj, wsKey, pValueObj->GetUnicodeText()); @@ -844,7 +845,8 @@ bool Document::getPropertyInternal(IJS_Context* cc, } CFX_WideString csProperty; vp >> csProperty; - pDictionary->SetStringFor(propName, PDF_EncodeText(csProperty)); + pDictionary->SetNewFor<CPDF_String>(propName, PDF_EncodeText(csProperty), + false); m_pFormFillEnv->SetChangeMark(); } return true; diff --git a/testing/libfuzzer/pdf_hint_table_fuzzer.cc b/testing/libfuzzer/pdf_hint_table_fuzzer.cc index 15e04d9b3d..b31d56eb8f 100644 --- a/testing/libfuzzer/pdf_hint_table_fuzzer.cc +++ b/testing/libfuzzer/pdf_hint_table_fuzzer.cc @@ -5,6 +5,7 @@ #include <cstdint> #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_hint_tables.h" #include "core/fpdfapi/parser/cpdf_linearized_header.h" @@ -62,15 +63,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { auto linearized_dict = pdfium::MakeUnique<CPDF_Dictionary>(); // Set initial value. - linearized_dict->SetBooleanFor("Linearized", true); + linearized_dict->SetNewFor<CPDF_Boolean>("Linearized", true); // Set first page end offset - linearized_dict->SetIntegerFor("E", GetData(&data32, &data, &size)); + linearized_dict->SetNewFor<CPDF_Number>("E", GetData(&data32, &data, &size)); // Set page count - linearized_dict->SetIntegerFor("N", GetData(&data32, &data, &size)); + linearized_dict->SetNewFor<CPDF_Number>("N", GetData(&data32, &data, &size)); // Set first page obj num - linearized_dict->SetIntegerFor("O", GetData(&data32, &data, &size)); + linearized_dict->SetNewFor<CPDF_Number>("O", GetData(&data32, &data, &size)); // Set first page no - linearized_dict->SetIntegerFor("P", GetData(&data32, &data, &size)); + linearized_dict->SetNewFor<CPDF_Number>("P", GetData(&data32, &data, &size)); auto hint_info = pdfium::MakeUnique<CPDF_Array>(); // Add primary hint stream offset @@ -78,7 +79,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Add primary hint stream size hint_info->AddNew<CPDF_Number>(GetData(&data32, &data, &size)); // Set hint stream info. - linearized_dict->SetFor("H", hint_info.release()); + linearized_dict->SetFor("H", std::move(hint_info)); const int shared_hint_table_offset = GetData(&data32, &data, &size); diff --git a/xfa/fxfa/app/xfa_fontmgr.cpp b/xfa/fxfa/app/xfa_fontmgr.cpp index ddac27d533..857c1d53f7 100644 --- a/xfa/fxfa/app/xfa_fontmgr.cpp +++ b/xfa/fxfa/app/xfa_fontmgr.cpp @@ -1839,7 +1839,7 @@ CFGAS_GEFont* CXFA_PDFFontMgr::FindFont(const CFX_ByteString& strPsName, CFGAS_FontMgr* pFDEFontMgr = m_pDoc->GetApp()->GetFDEFontMgr(); for (const auto& it : *pFontSetDict) { const CFX_ByteString& key = it.first; - CPDF_Object* pObj = it.second; + CPDF_Object* pObj = it.second.get(); if (!PsNameMatchDRFontName(name.AsStringC(), bBold, bItalic, key, bStrictMatch)) { continue; |