summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2016-01-08 14:37:26 -0800
committerTom Sepez <tsepez@chromium.org>2016-01-08 14:37:26 -0800
commita893a05a5c8e1f666cbf7cf9043f5687bd06d084 (patch)
treeca5c579ab14377fc371fdb457eccbd97d9fee1ee
parent4a24ad858484ecdf9b49481e63060e4d476cf1c7 (diff)
downloadpdfium-a893a05a5c8e1f666cbf7cf9043f5687bd06d084.tar.xz
Use unique_ptr in fpdf_page/.
Make m_InternalStage an enum. Use safe types to detect overflow. R=thestig@chromium.org Review URL: https://codereview.chromium.org/1568373003 .
-rw-r--r--core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp16
-rw-r--r--core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp107
-rw-r--r--core/src/fpdfapi/fpdf_page/pageint.h19
3 files changed, 60 insertions, 82 deletions
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
index cfc581f4c8..d0cf9ed719 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp
@@ -142,9 +142,6 @@ CPDF_StreamContentParser::CPDF_StreamContentParser(
CPDF_StreamContentParser::~CPDF_StreamContentParser() {
ClearAllParams();
- for (int i = 0; i < m_StateStack.GetSize(); ++i) {
- delete m_StateStack[i];
- }
FX_Free(m_pPathPoints);
if (m_pLastImageDict) {
m_pLastImageDict->Release();
@@ -937,19 +934,16 @@ void CPDF_StreamContentParser::Handle_EndPath() {
AddPathObject(0, FALSE);
}
void CPDF_StreamContentParser::Handle_SaveGraphState() {
- CPDF_AllStates* pStates = new CPDF_AllStates;
+ std::unique_ptr<CPDF_AllStates> pStates(new CPDF_AllStates);
pStates->Copy(*m_pCurStates);
- m_StateStack.Add(pStates);
+ m_StateStack.push_back(std::move(pStates));
}
void CPDF_StreamContentParser::Handle_RestoreGraphState() {
- int size = m_StateStack.GetSize();
- if (size == 0) {
+ if (m_StateStack.empty())
return;
- }
- CPDF_AllStates* pStates = m_StateStack.GetAt(size - 1);
+ std::unique_ptr<CPDF_AllStates> pStates = std::move(m_StateStack.back());
+ m_StateStack.pop_back();
m_pCurStates->Copy(*pStates);
- delete pStates;
- m_StateStack.RemoveAt(size - 1);
}
void CPDF_StreamContentParser::Handle_Rectangle() {
if (m_Options.m_bTextOnly) {
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
index 8846c023e1..33a566c87b 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
@@ -12,6 +12,7 @@
#include "core/include/fpdfapi/fpdf_page.h"
#include "core/include/fxcodec/fx_codec.h"
#include "core/include/fxcrt/fx_ext.h"
+#include "core/include/fxcrt/fx_safe_types.h"
namespace {
@@ -889,35 +890,18 @@ bool CPDF_StreamParser::PositionIsInBounds() const {
return m_Pos < m_Size;
}
-#define PAGEPARSE_STAGE_GETCONTENT 1
-#define PAGEPARSE_STAGE_PARSE 2
-#define PAGEPARSE_STAGE_CHECKCLIP 3
-CPDF_ContentParser::CPDF_ContentParser() {
- m_pParser = NULL;
- m_pStreamArray = NULL;
- m_pSingleStream = NULL;
- m_pData = NULL;
- m_Status = Ready;
- m_pType3Char = NULL;
-}
+CPDF_ContentParser::CPDF_ContentParser()
+ : m_Status(Ready),
+ m_InternalStage(STAGE_GETCONTENT),
+ m_pObjects(nullptr),
+ m_bForm(false),
+ m_pType3Char(nullptr),
+ m_pData(nullptr),
+ m_Size(0),
+ m_CurrentOffset(0) {}
CPDF_ContentParser::~CPDF_ContentParser() {
- Clear();
-}
-void CPDF_ContentParser::Clear() {
- delete m_pParser;
- delete m_pSingleStream;
- if (m_pStreamArray) {
- for (FX_DWORD i = 0; i < m_nStreams; i++)
- delete m_pStreamArray[i];
- FX_Free(m_pStreamArray);
- }
if (!m_pSingleStream)
FX_Free(m_pData);
- m_pParser = NULL;
- m_pStreamArray = NULL;
- m_pSingleStream = NULL;
- m_pData = NULL;
- m_Status = Ready;
}
void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) {
if (m_Status != Ready || !pPage || !pPage->m_pDocument ||
@@ -931,7 +915,7 @@ void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) {
m_Options = *pOptions;
}
m_Status = ToBeContinued;
- m_InternalStage = PAGEPARSE_STAGE_GETCONTENT;
+ m_InternalStage = STAGE_GETCONTENT;
m_CurrentOffset = 0;
CPDF_Object* pContent = pPage->m_pFormDict->GetElementValue("Contents");
@@ -941,15 +925,14 @@ void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) {
}
if (CPDF_Stream* pStream = pContent->AsStream()) {
m_nStreams = 0;
- m_pSingleStream = new CPDF_StreamAcc;
+ m_pSingleStream.reset(new CPDF_StreamAcc);
m_pSingleStream->LoadAllData(pStream, FALSE);
} else if (CPDF_Array* pArray = pContent->AsArray()) {
m_nStreams = pArray->GetCount();
- if (m_nStreams == 0) {
+ if (m_nStreams)
+ m_StreamArray.resize(m_nStreams);
+ else
m_Status = Done;
- return;
- }
- m_pStreamArray = FX_Alloc(CPDF_StreamAcc*, m_nStreams);
} else {
m_Status = Done;
}
@@ -985,11 +968,10 @@ void CPDF_ContentParser::Start(CPDF_Form* pForm,
}
}
CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDict("Resources");
- m_pParser = new CPDF_StreamContentParser(
+ m_pParser.reset(new CPDF_StreamContentParser(
pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources,
pParentMatrix, pForm, pResources, &form_bbox, pOptions, pGraphicStates,
- level);
-
+ level));
m_pParser->GetCurStates()->m_CTM = form_matrix;
m_pParser->GetCurStates()->m_ParentMatrix = form_matrix;
if (ClipPath.NotNull()) {
@@ -1005,73 +987,70 @@ void CPDF_ContentParser::Start(CPDF_Form* pForm,
pData->m_pSoftMask = NULL;
}
m_nStreams = 0;
- m_pSingleStream = new CPDF_StreamAcc;
+ m_pSingleStream.reset(new CPDF_StreamAcc);
m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE);
m_pData = (uint8_t*)m_pSingleStream->GetData();
m_Size = m_pSingleStream->GetSize();
m_Status = ToBeContinued;
- m_InternalStage = PAGEPARSE_STAGE_PARSE;
+ m_InternalStage = STAGE_PARSE;
m_CurrentOffset = 0;
}
void CPDF_ContentParser::Continue(IFX_Pause* pPause) {
int steps = 0;
while (m_Status == ToBeContinued) {
- if (m_InternalStage == PAGEPARSE_STAGE_GETCONTENT) {
+ if (m_InternalStage == STAGE_GETCONTENT) {
if (m_CurrentOffset == m_nStreams) {
- if (m_pStreamArray) {
- m_Size = 0;
- FX_DWORD i;
- for (i = 0; i < m_nStreams; i++) {
- FX_DWORD size = m_pStreamArray[i]->GetSize();
- if (m_Size + size + 1 <= m_Size) {
- m_Status = Done;
- return;
- }
- m_Size += size + 1;
+ if (!m_StreamArray.empty()) {
+ FX_SAFE_DWORD safeSize = 0;
+ for (const auto& stream : m_StreamArray) {
+ safeSize += stream->GetSize();
+ safeSize += 1;
+ }
+ if (!safeSize.IsValid()) {
+ m_Status = Done;
+ return;
}
+ m_Size = safeSize.ValueOrDie();
m_pData = FX_Alloc(uint8_t, m_Size);
FX_DWORD pos = 0;
- for (i = 0; i < m_nStreams; i++) {
- FXSYS_memcpy(m_pData + pos, m_pStreamArray[i]->GetData(),
- m_pStreamArray[i]->GetSize());
- pos += m_pStreamArray[i]->GetSize() + 1;
- m_pData[pos - 1] = ' ';
- delete m_pStreamArray[i];
+ for (const auto& stream : m_StreamArray) {
+ FXSYS_memcpy(m_pData + pos, stream->GetData(), stream->GetSize());
+ pos += stream->GetSize();
+ m_pData[pos++] = ' ';
}
- FX_Free(m_pStreamArray);
- m_pStreamArray = NULL;
+ m_StreamArray.clear();
} else {
m_pData = (uint8_t*)m_pSingleStream->GetData();
m_Size = m_pSingleStream->GetSize();
}
- m_InternalStage = PAGEPARSE_STAGE_PARSE;
+ m_InternalStage = STAGE_PARSE;
m_CurrentOffset = 0;
} else {
CPDF_Array* pContent = m_pObjects->m_pFormDict->GetArray("Contents");
- m_pStreamArray[m_CurrentOffset] = new CPDF_StreamAcc;
+ m_StreamArray[m_CurrentOffset].reset(new CPDF_StreamAcc);
CPDF_Stream* pStreamObj = ToStream(
pContent ? pContent->GetElementValue(m_CurrentOffset) : nullptr);
- m_pStreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE);
+ m_StreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE);
m_CurrentOffset++;
}
}
- if (m_InternalStage == PAGEPARSE_STAGE_PARSE) {
+ if (m_InternalStage == STAGE_PARSE) {
if (!m_pParser) {
- m_pParser = new CPDF_StreamContentParser(
+ m_pParser.reset(new CPDF_StreamContentParser(
m_pObjects->m_pDocument, m_pObjects->m_pPageResources, nullptr,
nullptr, m_pObjects, m_pObjects->m_pResources, &m_pObjects->m_BBox,
- &m_Options, nullptr, 0);
+ &m_Options, nullptr, 0));
m_pParser->GetCurStates()->m_ColorState.GetModify()->Default();
}
if (m_CurrentOffset >= m_Size) {
- m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP;
+ m_InternalStage = STAGE_CHECKCLIP;
} else {
m_CurrentOffset +=
m_pParser->Parse(m_pData + m_CurrentOffset,
m_Size - m_CurrentOffset, PARSE_STEP_LIMIT);
}
}
- if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) {
+ if (m_InternalStage == STAGE_CHECKCLIP) {
if (m_pType3Char) {
m_pType3Char->m_bColored = m_pParser->IsColored();
m_pType3Char->m_Width =
diff --git a/core/src/fpdfapi/fpdf_page/pageint.h b/core/src/fpdfapi/fpdf_page/pageint.h
index 69f06881f9..b162dc5633 100644
--- a/core/src/fpdfapi/fpdf_page/pageint.h
+++ b/core/src/fpdfapi/fpdf_page/pageint.h
@@ -268,7 +268,7 @@ class CPDF_StreamContentParser {
FX_BOOL m_bColored;
FX_FLOAT m_Type3Data[6];
FX_BOOL m_bResourceMissing;
- CFX_ArrayTemplate<CPDF_AllStates*> m_StateStack;
+ std::vector<std::unique_ptr<CPDF_AllStates>> m_StateStack;
};
class CPDF_ContentParser {
public:
@@ -287,21 +287,26 @@ class CPDF_ContentParser {
int level);
void Continue(IFX_Pause* pPause);
- protected:
- void Clear();
+ private:
+ enum InternalStage {
+ STAGE_GETCONTENT = 1,
+ STAGE_PARSE,
+ STAGE_CHECKCLIP,
+ };
+
ParseStatus m_Status;
+ InternalStage m_InternalStage;
CPDF_PageObjects* m_pObjects;
FX_BOOL m_bForm;
CPDF_ParseOptions m_Options;
CPDF_Type3Char* m_pType3Char;
- int m_InternalStage;
- CPDF_StreamAcc* m_pSingleStream;
- CPDF_StreamAcc** m_pStreamArray;
FX_DWORD m_nStreams;
+ std::unique_ptr<CPDF_StreamAcc> m_pSingleStream;
+ std::vector<std::unique_ptr<CPDF_StreamAcc>> m_StreamArray;
uint8_t* m_pData;
FX_DWORD m_Size;
- class CPDF_StreamContentParser* m_pParser;
FX_DWORD m_CurrentOffset;
+ std::unique_ptr<CPDF_StreamContentParser> m_pParser;
};
class CPDF_AllStates : public CPDF_GraphicStates {
public: