From 0e606b5ecd6e45f74391f110cc1fe0cce0e80c64 Mon Sep 17 00:00:00 2001 From: tsepez Date: Fri, 18 Nov 2016 16:22:41 -0800 Subject: Make CPDF_Dictionary use unique pointers. 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 --- core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp | 25 ++--- core/fpdfapi/edit/fpdf_edit_create.cpp | 20 ++-- core/fpdfapi/font/cpdf_font.cpp | 9 +- core/fpdfapi/font/cpdf_fontencoding.cpp | 8 +- core/fpdfapi/page/cpdf_allstates.cpp | 4 +- core/fpdfapi/page/cpdf_colorspace.cpp | 2 +- core/fpdfapi/page/cpdf_docpagedata.cpp | 13 ++- core/fpdfapi/page/cpdf_image.cpp | 72 +++++++-------- core/fpdfapi/page/cpdf_streamcontentparser.cpp | 19 ++-- core/fpdfapi/page/cpdf_streamparser.cpp | 13 ++- core/fpdfapi/parser/cfdf_document.cpp | 6 +- core/fpdfapi/parser/cpdf_data_avail.cpp | 6 +- core/fpdfapi/parser/cpdf_dictionary.cpp | 102 +++++---------------- core/fpdfapi/parser/cpdf_dictionary.h | 41 +++++---- core/fpdfapi/parser/cpdf_document.cpp | 117 ++++++++++++------------ core/fpdfapi/parser/cpdf_document_unittest.cpp | 30 +++--- core/fpdfapi/parser/cpdf_object_unittest.cpp | 48 +++++----- core/fpdfapi/parser/cpdf_parser.cpp | 13 +-- core/fpdfapi/parser/cpdf_security_handler.cpp | 24 +++-- core/fpdfapi/parser/cpdf_stream.cpp | 7 +- core/fpdfapi/parser/cpdf_string.cpp | 9 +- core/fpdfapi/parser/cpdf_string.h | 4 +- core/fpdfapi/parser/cpdf_syntax_parser.cpp | 11 ++- core/fpdfapi/parser/fpdf_parser_utility.cpp | 3 +- core/fpdfdoc/cpdf_annot.cpp | 3 +- core/fpdfdoc/cpdf_annotlist.cpp | 14 ++- core/fpdfdoc/cpdf_filespec.cpp | 9 +- core/fpdfdoc/cpdf_filespec_unittest.cpp | 9 +- core/fpdfdoc/cpdf_formcontrol.cpp | 9 +- core/fpdfdoc/cpdf_formfield.cpp | 48 +++++----- core/fpdfdoc/cpdf_formfield_unittest.cpp | 17 ++-- core/fpdfdoc/cpdf_interform.cpp | 92 +++++++++---------- core/fpdfdoc/cpvt_fontmap.cpp | 5 +- core/fpdfdoc/cpvt_generateap.cpp | 103 ++++++++++----------- core/fxge/dib/fx_dib_engine_unittest.cpp | 4 +- 35 files changed, 457 insertions(+), 462 deletions(-) (limited to 'core') 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(); pStream->SetData(buf.GetBuffer(), buf.GetLength()); - pPageDict->SetReferenceFor("Contents", m_pDocument, pStream); + pPageDict->SetNewFor("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(); - m_pPage->m_pFormDict->SetReferenceFor("Resources", m_pDocument, - m_pPage->m_pResources); + m_pPage->m_pFormDict->SetNewFor( + "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(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(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("Type", "XObject"); + pFormDict->SetNewFor("Subtype", "Form"); pFormDict->SetRectFor("BBox", bbox); CPDF_Stream* pStream = m_pDocument->NewIndirect(); @@ -179,5 +181,6 @@ void CPDF_PageContentGenerator::TransformContent(CFX_Matrix& matrix) { } CPDF_Stream* pStream = m_pDocument->NewIndirect(); pStream->SetData(buf.GetBuffer(), buf.GetLength()); - m_pPage->m_pFormDict->SetReferenceFor("Contents", m_pDocument, pStream); + m_pPage->m_pFormDict->SetNewFor("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("Length", static_cast(m_dwSize)); + m_pDict->SetNewFor("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( + "Length", static_cast(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( + "Length", static_cast(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 +#include #include #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("Type", "Font"); + pDict->SetNewFor("Subtype", "Type1"); + pDict->SetNewFor("BaseFont", fontname); + pDict->SetNewFor("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 + #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 pPool) { } const uint16_t* pStandard = PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI); - CPDF_Array* pDiff = new CPDF_Array; + auto pDiff = pdfium::MakeUnique(); 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 pPool) { } CPDF_Dictionary* pDict = new CPDF_Dictionary(pPool); - pDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); - pDict->SetFor("Differences", pDiff); + pDict->SetNewFor("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 + #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::Load(CPDF_Document* pDoc, for (const auto& it : *pDict) { std::unique_ptr 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 +#include #include #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(); - pDict->SetNameFor("Type", "Font"); - pDict->SetNameFor("Subtype", "Type1"); - pDict->SetNameFor("BaseFont", fontName); + pDict->SetNewFor("Type", "Font"); + pDict->SetNewFor("Subtype", "Type1"); + pDict->SetNewFor("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 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 #include +#include #include #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("Type", "XObject"); + pDict->SetNewFor("Subtype", "Image"); + pDict->SetNewFor("Width", width); + pDict->SetNewFor("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("Decode"); for (int n = 0; n < 4; n++) { pDecode->AddNew(1); pDecode->AddNew(0); } - pDict->SetFor("Decode", pDecode); } - pDict->SetNameFor("ColorSpace", csname); - pDict->SetIntegerFor("BitsPerComponent", bits); - pDict->SetNameFor("Filter", "DCTDecode"); + pDict->SetNewFor("ColorSpace", csname); + pDict->SetNewFor("BitsPerComponent", bits); + pDict->SetNewFor("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("DecodeParms"); + pParms->SetNewFor("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("Type", "XObject"); + pDict->SetNewFor("Subtype", "Image"); + pDict->SetNewFor("Width", BitmapWidth); + pDict->SetNewFor("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("ImageMask", true); if (reset_a == 0) { - CPDF_Array* pArray = new CPDF_Array; + CPDF_Array* pArray = pDict->SetNewFor("Decode"); pArray->AddNew(1); pArray->AddNew(0); - pDict->SetFor("Decode", pArray); } } else { - CPDF_Array* pCS = new CPDF_Array; + CPDF_Array* pCS = pDict->SetNewFor("ColorSpace"); pCS->AddNew("Indexed"); pCS->AddNew("DeviceRGB"); pCS->AddNew(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(ct, true); - pDict->SetFor("ColorSpace", pCS); } - pDict->SetIntegerFor("BitsPerComponent", 1); + pDict->SetNewFor("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(m_pDocument, pCTS->GetObjNum()); - pDict->SetReferenceFor("ColorSpace", m_pDocument, pCS); + pDict->SetNewFor("ColorSpace", m_pDocument, + pCS->GetObjNum()); } else { - pDict->SetNameFor("ColorSpace", "DeviceGray"); + pDict->SetNewFor("ColorSpace", "DeviceGray"); } - pDict->SetIntegerFor("BitsPerComponent", 8); + pDict->SetNewFor("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("ColorSpace", "DeviceRGB"); + pDict->SetNewFor("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("Type", "XObject"); + pMaskDict->SetNewFor("Subtype", "Image"); + pMaskDict->SetNewFor("Width", maskWidth); + pMaskDict->SetNewFor("Height", maskHeight); + pMaskDict->SetNewFor("ColorSpace", "DeviceGray"); + pMaskDict->SetNewFor("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("Length", mask_size); + pDict->SetNewFor( "SMask", m_pDocument, - m_pDocument->NewIndirect(mask_buf, mask_size, pMaskDict)); + m_pDocument->NewIndirect(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 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(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 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(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("Subtype", "Image"); std::unique_ptr 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 +#include + #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("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 +#include + #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(); - pDoc->m_pRootDict->SetFor("FDF", - new CPDF_Dictionary(pDoc->GetByteStringPool())); + pDoc->m_pRootDict->SetNewFor("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& 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& 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_Dictionary::CloneNonCyclic( pVisited->insert(this); auto pCopy = pdfium::MakeUnique(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_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 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(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(key); pArray->AddNew(rect.left); pArray->AddNew(rect.bottom); pArray->AddNew(rect.right); pArray->AddNew(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(key); pArray->AddNew(matrix.a); pArray->AddNew(matrix.b); pArray->AddNew(matrix.c); pArray->AddNew(matrix.d); pArray->AddNew(matrix.e); pArray->AddNew(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 +#include #include #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::iterator; - using const_iterator = std::map::const_iterator; + using const_iterator = + std::map>::const_iterator; CPDF_Dictionary(); explicit CPDF_Dictionary(const CFX_WeakPtr& 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 pObj); + + // Creates a new object owned by the dictionary and returns an unowned + // pointer to it. + template + typename std::enable_if::value, T*>::type SetNewFor( + const CFX_ByteString& key, + Args... args) { + return static_cast(SetFor(key, pdfium::MakeUnique(args...))); + } + template + typename std::enable_if::value, T*>::type SetNewFor( + const CFX_ByteString& key, + Args... args) { + return static_cast( + SetFor(key, pdfium::MakeUnique(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* visited) const override; CFX_WeakPtr m_pPool; - std::map m_Map; + std::map> 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 #include +#include #include #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("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("Subtype", "TrueType"); + pBaseDict->SetNewFor("BaseFont", basefont); + pBaseDict->SetNewFor("FirstChar", 32); + pBaseDict->SetNewFor("LastChar", 255); + pBaseDict->SetFor("Widths", pdfium::WrapUnique(pWidths)); } std::unique_ptr CalculateFontDesc(CPDF_Document* pDoc, @@ -321,14 +323,14 @@ std::unique_ptr CalculateFontDesc(CPDF_Document* pDoc, int32_t stemV) { auto pFontDesc = pdfium::MakeUnique(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("Type", "FontDescriptor"); + pFontDesc->SetNewFor("FontName", basefont); + pFontDesc->SetNewFor("Flags", flags); + pFontDesc->SetFor("FontBBox", pdfium::WrapUnique(bbox)); + pFontDesc->SetNewFor("ItalicAngle", italicangle); + pFontDesc->SetNewFor("Ascent", ascend); + pFontDesc->SetNewFor("Descent", descend); + pFontDesc->SetNewFor("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(); - m_pRootDict->SetNameFor("Type", "Catalog"); + m_pRootDict->SetNewFor("Type", "Catalog"); CPDF_Dictionary* pPages = NewIndirect(); - pPages->SetNameFor("Type", "Pages"); - pPages->SetNumberFor("Count", 0); - pPages->SetFor("Kids", new CPDF_Array); - m_pRootDict->SetReferenceFor("Pages", this, pPages); + pPages->SetNewFor("Type", "Pages"); + pPages->SetNewFor("Count", 0); + pPages->SetNewFor("Kids"); + m_pRootDict->SetNewFor("Pages", this, pPages->GetObjNum()); m_pInfoDict = NewIndirect(); } CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) { CPDF_Dictionary* pDict = NewIndirect(); - pDict->SetNameFor("Type", "Page"); + pDict->SetNewFor("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(i, this, pPageDict->GetObjNum()); - pPageDict->SetReferenceFor("Parent", this, pPages->GetObjNum()); + pPageDict->SetNewFor("Parent", this, + pPages->GetObjNum()); } else { pKidList->RemoveAt(i); } - pPages->SetIntegerFor( + pPages->SetNewFor( "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( + "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("Kids"); pPagesList->AddNew(this, pPageDict->GetObjNum()); - pPages->SetIntegerFor("Count", nPages + 1); - pPageDict->SetReferenceFor("Parent", this, pPages->GetObjNum()); + pPages->SetNewFor("Count", nPages + 1); + pPageDict->SetNewFor("Parent", this, pPages->GetObjNum()); ResetTraversal(); } else { std::set stack = {pPages}; @@ -780,9 +781,9 @@ size_t CPDF_Document::CalculateEncodingDict(int charset, return i; CPDF_Dictionary* pEncodingDict = NewIndirect(); - pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); + pEncodingDict->SetNewFor("BaseEncoding", "WinAnsiEncoding"); - CPDF_Array* pArray = new CPDF_Array; + CPDF_Array* pArray = pEncodingDict->SetNewFor("Differences"); pArray->AddNew(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(name.IsEmpty() ? ".notdef" : name); } - pEncodingDict->SetFor("Differences", pArray); - pBaseDict->SetReferenceFor("Encoding", this, pEncodingDict); + pBaseDict->SetNewFor("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("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("Subtype", "Type0"); + pBaseDict->SetNewFor("BaseFont", basefont); + pBaseDict->SetNewFor("Encoding", cmap); + pFontDict->SetNewFor("Type", "Font"); + pFontDict->SetNewFor("Subtype", "CIDFontType2"); + pFontDict->SetNewFor("BaseFont", basefont); + + CPDF_Dictionary* pCIDSysInfo = + pFontDict->SetNewFor("CIDSystemInfo"); + pCIDSysInfo->SetNewFor("Registry", "Adobe", false); + pCIDSysInfo->SetNewFor("Ordering", ordering, false); + pCIDSysInfo->SetNewFor("Supplement", supplement); + + CPDF_Array* pArray = pBaseDict->SetNewFor("DescendantFonts"); pArray->AddNew(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(); - pBaseDict->SetNameFor("Type", "Font"); + pBaseDict->SetNewFor("Type", "Font"); std::unique_ptr 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("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("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(); - pBaseDict->SetNameFor("Type", "Font"); + pBaseDict->SetNewFor("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("Encoding", "WinAnsiEncoding"); } else { CalculateEncodingDict(pLogFont->lfCharSet, pBaseDict); } @@ -1037,9 +1039,10 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, std::unique_ptr 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("CapHeight", capheight); + pFontDict->SetNewFor( + "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 +#include #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 kids, int count) { CPDF_Array* pUnowned = pDoc->AddIndirectObject(std::move(kids))->AsArray(); CPDF_Dictionary* pageNode = pDoc->NewIndirect(); - 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("Type", "Pages", false); + pageNode->SetNewFor("Kids", pDoc, pUnowned->GetObjNum()); + pageNode->SetNewFor("Count", count); + for (size_t i = 0; i < pUnowned->GetCount(); i++) { + pUnowned->GetDictAt(i)->SetNewFor("Parent", pDoc, + pageNode->GetObjNum()); + } return pageNode; } std::unique_ptr CreateNumberedPage(size_t number) { auto page = pdfium::MakeUnique(); - page->SetStringFor("Type", "Page"); - page->SetIntegerFor("PageNumbering", number); + page->SetNewFor("Type", "Page", false); + page->SetNewFor("PageNumbering", static_cast(number)); return page; } @@ -79,7 +85,8 @@ class CPDF_TestDocumentForPages : public CPDF_Document { CreatePageTreeNode(std::move(allPages), this, 7); m_pOwnedRootDict = pdfium::MakeUnique(); - m_pOwnedRootDict->SetReferenceFor("Pages", this, pagesDict); + m_pOwnedRootDict->SetNewFor("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("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()); auto dict = pdfium::MakeUnique(); - dict->SetBooleanFor("Linearized", true); + dict->SetNewFor("Linearized", true); const int page_count = 100; - dict->SetIntegerFor("N", page_count); + dict->SetNewFor("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 #include +#include #include #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(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("bool", false); + m_DictObj->SetNewFor("num", 0.23f); // Stream object. const char content[] = "abcdefghijklmnopqrstuvwxyz"; size_t buf_len = FX_ArraySize(content); uint8_t* buf = reinterpret_cast(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("key1", L" test dict"); + m_StreamDictObj->SetNewFor("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(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(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(2); CPDF_Dictionary* dict_val = arr->InsertNewAt(12); - dict_val->SetFor("key1", new CPDF_String(nullptr, "Linda", false)); - dict_val->SetFor("key2", new CPDF_String(nullptr, "Zoe", false)); + dict_val->SetNewFor("key1", "Linda", false); + dict_val->SetNewFor("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("key1", "John", false); + stream_dict->SetNewFor("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 dict(new CPDF_Dictionary()); - dict->SetReferenceFor("foo", &objects_holder, 1234); + dict->SetNewFor("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_Dictionary* dict_obj = arr_obj->InsertNewAt(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 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 stream_obj( - new CPDF_Stream(nullptr, 0, dict_obj)); - dict_obj->SetFor("stream", stream_obj.get()); - + auto dict_obj = pdfium::MakeUnique(); + CPDF_Stream* stream_obj = + dict_obj->SetNewFor("stream", nullptr, 0, dict_obj.get()); // Clone this object to see whether stack overflow will be triggered. std::unique_ptr 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(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 dict(new CPDF_Dictionary); - CPDF_Object* pObj = new CPDF_Number(42); - dict->SetFor("clams", pObj); + CPDF_Object* pObj = dict->SetNewFor("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 +#include #include #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( + 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 +#include +#include +#include + #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("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("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("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(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(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("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("Length", static_cast(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(pFile->GetSize()); if (m_pDict) - m_pDict->SetIntegerFor("Length", m_dwSize); + m_pDict->SetNewFor("Length", static_cast(m_dwSize)); } std::unique_ptr 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("Length", static_cast(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 + #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 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 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 + #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 pPool, const CFX_ByteString& str, bool bHex); - explicit CPDF_String(const CFX_WideString& str); + CPDF_String(CFX_WeakPtr 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 +#include #include #include "core/fpdfapi/cpdf_modulemgr.h" @@ -458,7 +460,7 @@ std::unique_ptr 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_SyntaxParser::GetObject( if (pDict->IsSignatureDict() && dwSignValuePos) { CFX_AutoRestorer 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_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_SyntaxParser::ReadStream( delete pDict; return nullptr; } - pDict->SetIntegerFor("Length", len); + pDict->SetNewFor("Length", static_cast(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(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 CreatePopupAnnot(CPDF_Annot* pAnnot, auto pAnnotDict = pdfium::MakeUnique(pDocument->GetByteStringPool()); - pAnnotDict->SetNameFor("Type", "Annot"); - pAnnotDict->SetNameFor("Subtype", "Popup"); - pAnnotDict->SetStringFor("T", pParentDict->GetStringFor("T")); - pAnnotDict->SetStringFor("Contents", sContents.UTF8Encode()); + pAnnotDict->SetNewFor("Type", "Annot"); + pAnnotDict->SetNewFor("Subtype", "Popup"); + pAnnotDict->SetNewFor("T", pParentDict->GetStringFor("T"), + false); + pAnnotDict->SetNewFor("Contents", sContents.UTF8Encode(), false); CFX_FloatRect rect = pParentDict->GetRectFor("Rect"); rect.Normalize(); @@ -47,7 +51,7 @@ std::unique_ptr CreatePopupAnnot(CPDF_Annot* pAnnot, popupRect.Translate(rect.left, rect.bottom - popupRect.Height()); pAnnotDict->SetRectFor("Rect", popupRect); - pAnnotDict->SetIntegerFor("F", 0); + pAnnotDict->SetNewFor("F", 0); auto pPopupAnnot = pdfium::MakeUnique(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& pPool) { m_pObj = new CPDF_Dictionary(pPool); - m_pObj->AsDictionary()->SetNameFor("Type", "Filespec"); + m_pObj->AsDictionary()->SetNewFor("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("F", CFX_ByteString::FromUnicode(wsStr), + false); + pDict->SetNewFor("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 str_obj(new CPDF_String(test_data.input)); + std::unique_ptr 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(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("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 str_obj(new CPDF_String(L"babababa")); + std::unique_ptr 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("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("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 #include +#include #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 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(key, bsEncodeText, false); if (m_Type == RichText && !bDefault) - m_pDict->SetStringFor("RV", bsEncodeText); + m_pDict->SetNewFor("RV", bsEncodeText, false); m_pDict->RemoveFor("I"); } else { - m_pDict->SetStringFor(bDefault ? "DV" : "V", PDF_EncodeText(csValue)); + m_pDict->SetNewFor(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("V", PDF_EncodeText(opt_value), false); } else { - CPDF_Array* pArray = new CPDF_Array; + CPDF_Array* pArray = m_pDict->SetNewFor("V"); for (int i = 0; i < CountOptions(); i++) { if (i == index || IsItemSelected(i)) { opt_value = GetOptionValue(i); pArray->AddNew(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("V", PDF_EncodeText(opt_value), false); + CPDF_Array* pI = m_pDict->SetNewFor("I"); pI->AddNew(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("Opt"); int iCount = pdfium::base::checked_cast(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("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("V", "Off"); } } else if (bChecked) { CFX_ByteString csIndex; csIndex.Format("%d", iControlIndex); - m_pDict->SetNameFor("V", csIndex); + m_pDict->SetNewFor("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("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(); - root->SetNameFor("T", "foo"); + root->SetNewFor("T", "foo"); name = FPDF_GetFullName(root); EXPECT_STREQ("foo", name.UTF8Encode().c_str()); CPDF_Dictionary* dict1 = obj_holder.NewIndirect(); - root->SetReferenceFor("Parent", &obj_holder, dict1); - dict1->SetNameFor("T", "bar"); + root->SetNewFor("Parent", &obj_holder, dict1->GetObjNum()); + dict1->SetNewFor("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("Parent"); name = FPDF_GetFullName(root); EXPECT_STREQ("bar.foo", name.UTF8Encode().c_str()); CPDF_Dictionary* dict3 = obj_holder.NewIndirect(); - dict2->SetReferenceFor("Parent", &obj_holder, dict3); + dict2->SetNewFor("Parent", &obj_holder, dict3->GetObjNum()); - dict3->SetNameFor("T", "qux"); + dict3->SetNewFor("T", "qux"); name = FPDF_GetFullName(root); EXPECT_STREQ("qux.bar.foo", name.UTF8Encode().c_str()); - dict3->SetReferenceFor("Parent", &obj_holder, root->GetObjNum()); + dict3->SetNewFor("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 #include #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(); - pDocument->GetRoot()->SetReferenceFor("AcroForm", pDocument, - pFormDict->GetObjNum()); + pDocument->GetRoot()->SetNewFor("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("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("DR"); + CPDF_Dictionary* pFonts = pDR->GetDictFor("Font"); - if (!pFonts) { - pFonts = new CPDF_Dictionary(pDocument->GetByteStringPool()); - pDR->SetFor("Font", pFonts); - } + if (!pFonts) + pFonts = pDR->SetNewFor("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(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 pClone = pTObj->CloneDirectObject(); if (pClone) - pDict->SetFor("T", pClone.release()); + pDict->SetFor("T", std::move(pClone)); else - pDict->SetNameFor("T", ""); + pDict->SetNewFor("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( + "F", CFX_ByteString::FromUnicode(wsFilePath), false); + pMainDict->SetNewFor("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("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(pDoc->GetByteStringPool()); - pFieldDict->SetFor("T", new CPDF_String(fullname)); + pFieldDict->SetNewFor("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("V", csBExport, false); else - pFieldDict->SetNameFor("V", csBExport); + pFieldDict->SetNewFor("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(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 #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(); - 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("Type", "Font"); + pFontDict->SetNewFor("Subtype", "Type1"); + pFontDict->SetNewFor("BaseFont", "Helvetica"); + pFontDict->SetNewFor("Encoding", "WinAnsiEncoding"); + pDRFontDict->SetNewFor(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(pDoc->GetByteStringPool()); - // Ownership passes to |pAnnotDict|. - pAPDict = pNewAPDict.release(); - pAnnotDict->SetFor("AP", pAPDict); - } + if (!pAPDict) + pAPDict = pAnnotDict->SetNewFor("AP"); + CPDF_Stream* pNormalStream = pAPDict->GetStreamFor("N"); if (!pNormalStream) { pNormalStream = pDoc->NewIndirect(); - pAPDict->SetReferenceFor("N", pDoc, pNormalStream); + pAPDict->SetNewFor("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(pDoc->GetByteStringPool()); - // Ownership passes to |pStreamResList|. - pStreamResFontList = pNewStreamResFontList.release(); - pStreamResList->SetFor("Font", pStreamResFontList); + if (!pStreamResFontList) + pStreamResFontList = pStreamResList->SetNewFor("Font"); + if (!pStreamResFontList->KeyExist(sFontName)) { + pStreamResFontList->SetNewFor(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(pDoc->GetByteStringPool()); - // Ownership passes to |pStreamResList|. - pStreamResFontList = pNewStreamResFontList.release(); - pStreamResList->SetFor("Font", pStreamResFontList); + pStreamResFontList = + pStreamResList->SetNewFor("Font"); + } + if (!pStreamResFontList->KeyExist(sFontName)) { + pStreamResFontList->SetNewFor(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 GenerateExtGStateDict( const CFX_ByteString& sBlendMode) { auto pGSDict = pdfium::MakeUnique(pAnnotDict.GetByteStringPool()); - pGSDict->SetStringFor("Type", "ExtGState"); + pGSDict->SetNewFor("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("CA", fOpacity); + pGSDict->SetNewFor("ca", fOpacity); + pGSDict->SetNewFor("AIS", false); + pGSDict->SetNewFor("BM", sBlendMode, false); auto pExtGStateDict = pdfium::MakeUnique(pAnnotDict.GetByteStringPool()); - pExtGStateDict->SetFor(sExtGSDictName, pGSDict.release()); + pExtGStateDict->SetFor(sExtGSDictName, std::move(pGSDict)); return pExtGStateDict; } @@ -573,14 +570,15 @@ std::unique_ptr GenerateResourceFontDict( CPDF_Document* pDoc, const CFX_ByteString& sFontDictName) { CPDF_Dictionary* pFontDict = pDoc->NewIndirect(); - pFontDict->SetNameFor("Type", "Font"); - pFontDict->SetNameFor("Subtype", "Type1"); - pFontDict->SetNameFor("BaseFont", "Helvetica"); - pFontDict->SetNameFor("Encoding", "WinAnsiEncoding"); + pFontDict->SetNewFor("Type", "Font"); + pFontDict->SetNewFor("Subtype", "Type1"); + pFontDict->SetNewFor("BaseFont", "Helvetica"); + pFontDict->SetNewFor("Encoding", "WinAnsiEncoding"); auto pResourceFontDict = pdfium::MakeUnique(pDoc->GetByteStringPool()); - pResourceFontDict->SetReferenceFor(sFontDictName, pDoc, pFontDict); + pResourceFontDict->SetNewFor(sFontDictName, pDoc, + pFontDict->GetObjNum()); return pResourceFontDict; } @@ -591,9 +589,9 @@ std::unique_ptr GenerateResourceDict( auto pResourceDict = pdfium::MakeUnique(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(); pNormalStream->SetData(sAppStream.GetBuffer(), sAppStream.GetSize()); - auto pAPDict = pdfium::MakeUnique(pDoc->GetByteStringPool()); - pAPDict->SetReferenceFor("N", pDoc, pNormalStream); - pAnnotDict->SetFor("AP", pAPDict.release()); + CPDF_Dictionary* pAPDict = pAnnotDict->SetNewFor("AP"); + pAPDict->SetNewFor("N", pDoc, pNormalStream->GetObjNum()); CPDF_Dictionary* pStreamDict = pNormalStream->GetDict(); - pStreamDict->SetIntegerFor("FormType", 1); - pStreamDict->SetStringFor("Subtype", "Form"); + pStreamDict->SetNewFor("FormType", 1); + pStreamDict->SetNewFor("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( + "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 dict_obj = pdfium::MakeUnique(); - dict_obj->SetFor("Width", new CPDF_Number(71000)); - dict_obj->SetFor("Height", new CPDF_Number(12500)); + dict_obj->SetNewFor("Width", 71000); + dict_obj->SetNewFor("Height", 12500); std::unique_ptr stream = pdfium::MakeUnique(nullptr, 0, dict_obj.release()); CPDF_DIBSource dib_source; -- cgit v1.2.3