From a105e003fd8ac96029f015f20ac8ad1dee8e6391 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Mon, 20 Mar 2017 11:51:32 -0700 Subject: Use std::vector> as word array. We never push nullptrs into this array, so remove some checks for nullness, but be really careful about bounds checking. Change-Id: I79960a4cc9a729b3d5985f297aea8c4b03ceb601 Reviewed-on: https://pdfium-review.googlesource.com/3103 Reviewed-by: Lei Zhang Commit-Queue: Tom Sepez --- core/fpdfdoc/cpdf_variabletext.cpp | 144 ++++++++++++++++++------------------- core/fpdfdoc/csection.cpp | 77 ++++++++------------ core/fpdfdoc/csection.h | 4 +- core/fpdfdoc/ctypeset.cpp | 70 ++++++++++-------- 4 files changed, 137 insertions(+), 158 deletions(-) diff --git a/core/fpdfdoc/cpdf_variabletext.cpp b/core/fpdfdoc/cpdf_variabletext.cpp index dcd3a0785a..d5746b1ce0 100644 --- a/core/fpdfdoc/cpdf_variabletext.cpp +++ b/core/fpdfdoc/cpdf_variabletext.cpp @@ -170,16 +170,12 @@ bool CPDF_VariableText::Iterator::PrevSection() { bool CPDF_VariableText::Iterator::GetWord(CPVT_Word& word) const { word.WordPlace = m_CurPos; CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex); - if (!pSection) - return false; - - if (!pdfium::IndexInBounds(pSection->m_LineArray, m_CurPos.nLineIndex)) + if (!pSection || + !pdfium::IndexInBounds(pSection->m_LineArray, m_CurPos.nLineIndex) || + !pdfium::IndexInBounds(pSection->m_WordArray, m_CurPos.nWordIndex)) { return false; - - CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(m_CurPos.nWordIndex); - if (!pWord) - return false; - + } + CPVT_WordInfo* pWord = pSection->m_WordArray[m_CurPos.nWordIndex].get(); word.Word = pWord->Word; word.nCharset = pWord->nCharset; word.fWidth = m_pVT->GetWordWidth(*pWord); @@ -197,13 +193,11 @@ bool CPDF_VariableText::Iterator::GetWord(CPVT_Word& word) const { bool CPDF_VariableText::Iterator::SetWord(const CPVT_Word& word) { CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex); - if (!pSection) - return false; - - CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(m_CurPos.nWordIndex); - if (!pWord) + if (!pSection || + !pdfium::IndexInBounds(pSection->m_WordArray, m_CurPos.nWordIndex)) { return false; - + } + CPVT_WordInfo* pWord = pSection->m_WordArray[m_CurPos.nWordIndex].get(); if (pWord->pWordProps) *pWord->pWordProps = word.WordProps; return true; @@ -329,25 +323,22 @@ CPVT_WordPlace CPDF_VariableText::InsertSection( CPVT_WordPlace wordplace = place; UpdateWordPlace(wordplace); - CPVT_WordPlace newplace = place; + CPVT_WordPlace result = place; if (CSection* pSection = m_SectionArray.GetAt(wordplace.nSecIndex)) { CPVT_WordPlace NewPlace(wordplace.nSecIndex + 1, 0, -1); CPVT_SectionInfo secinfo; AddSection(NewPlace, secinfo); - newplace = NewPlace; + result = NewPlace; if (CSection* pNewSection = m_SectionArray.GetAt(NewPlace.nSecIndex)) { - for (int32_t w = wordplace.nWordIndex + 1, - sz = pSection->m_WordArray.GetSize(); - w < sz; w++) { - if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(w)) { - NewPlace.nWordIndex++; - pNewSection->AddWord(NewPlace, *pWord); - } + for (int32_t w = wordplace.nWordIndex + 1; + w < pdfium::CollectionSize(pSection->m_WordArray); ++w) { + NewPlace.nWordIndex++; + pNewSection->AddWord(NewPlace, *pSection->m_WordArray[w]); } } ClearSectionRightWords(wordplace); } - return newplace; + return result; } CPVT_WordPlace CPDF_VariableText::InsertText(const CPVT_WordPlace& place, @@ -478,7 +469,7 @@ int32_t CPDF_VariableText::WordPlaceToWordIndex( for (i = 0, sz = m_SectionArray.GetSize(); i < sz && i < newplace.nSecIndex; i++) { if (CSection* pSection = m_SectionArray.GetAt(i)) { - nIndex += pSection->m_WordArray.GetSize(); + nIndex += pdfium::CollectionSize(pSection->m_WordArray); if (i != m_SectionArray.GetSize() - 1) nIndex += kReturnLength; } @@ -494,7 +485,7 @@ CPVT_WordPlace CPDF_VariableText::WordIndexToWordPlace(int32_t index) const { bool bFind = false; for (int32_t i = 0, sz = m_SectionArray.GetSize(); i < sz; i++) { if (CSection* pSection = m_SectionArray.GetAt(i)) { - nIndex += pSection->m_WordArray.GetSize(); + nIndex += pdfium::CollectionSize(pSection->m_WordArray); if (nIndex == index) { place = pSection->GetEndWordPlace(); bFind = true; @@ -679,10 +670,11 @@ CPVT_WordPlace CPDF_VariableText::GetSectionEndPlace( int32_t CPDF_VariableText::GetTotalWords() const { int32_t nTotal = 0; for (int32_t i = 0, sz = m_SectionArray.GetSize(); i < sz; i++) { - if (CSection* pSection = m_SectionArray.GetAt(i)) - nTotal += (pSection->m_WordArray.GetSize() + kReturnLength); + if (CSection* pSection = m_SectionArray.GetAt(i)) { + nTotal += pdfium::CollectionSize(pSection->m_WordArray) + + kReturnLength; + } } - return nTotal - kReturnLength; } @@ -735,24 +727,24 @@ CPVT_WordPlace CPDF_VariableText::AddWord(const CPVT_WordPlace& place, bool CPDF_VariableText::GetWordInfo(const CPVT_WordPlace& place, CPVT_WordInfo& wordinfo) { - if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) { - if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(place.nWordIndex)) { - wordinfo = *pWord; - return true; - } + CSection* pSection = m_SectionArray.GetAt(place.nSecIndex); + if (!pSection || + !pdfium::IndexInBounds(pSection->m_WordArray, place.nWordIndex)) { + return false; } - return false; + wordinfo = *pSection->m_WordArray[place.nWordIndex]; + return true; } bool CPDF_VariableText::SetWordInfo(const CPVT_WordPlace& place, const CPVT_WordInfo& wordinfo) { - if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) { - if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(place.nWordIndex)) { - *pWord = wordinfo; - return true; - } + CSection* pSection = m_SectionArray.GetAt(place.nSecIndex); + if (!pSection || + !pdfium::IndexInBounds(pSection->m_WordArray, place.nWordIndex)) { + return false; } - return false; + *pSection->m_WordArray[place.nWordIndex] = wordinfo; + return true; } bool CPDF_VariableText::GetLineInfo(const CPVT_WordPlace& place, @@ -876,13 +868,14 @@ int32_t CPDF_VariableText::GetHorzScale(const CPVT_WordInfo& WordInfo) { void CPDF_VariableText::ClearSectionRightWords(const CPVT_WordPlace& place) { CPVT_WordPlace wordplace = AdjustLineHeader(place, true); - if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) { - for (int32_t w = pSection->m_WordArray.GetSize() - 1; - w > wordplace.nWordIndex; w--) { - delete pSection->m_WordArray.GetAt(w); - pSection->m_WordArray.RemoveAt(w); - } + CSection* pSection = m_SectionArray.GetAt(place.nSecIndex); + if (!pSection || + !pdfium::IndexInBounds(pSection->m_WordArray, wordplace.nWordIndex + 1)) { + return; } + pSection->m_WordArray.erase( + pSection->m_WordArray.begin() + wordplace.nWordIndex + 1, + pSection->m_WordArray.end()); } CPVT_WordPlace CPDF_VariableText::AdjustLineHeader(const CPVT_WordPlace& place, @@ -895,14 +888,14 @@ CPVT_WordPlace CPDF_VariableText::AdjustLineHeader(const CPVT_WordPlace& place, bool CPDF_VariableText::ClearEmptySection(const CPVT_WordPlace& place) { if (place.nSecIndex == 0 && m_SectionArray.GetSize() == 1) return false; - if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) { - if (pSection->m_WordArray.GetSize() == 0) { - delete pSection; - m_SectionArray.RemoveAt(place.nSecIndex); - return true; - } - } - return false; + + CSection* pSection = m_SectionArray.GetAt(place.nSecIndex); + if (!pSection || !pSection->m_WordArray.empty()) + return false; + + delete pSection; + m_SectionArray.RemoveAt(place.nSecIndex); + return true; } void CPDF_VariableText::ClearEmptySections(const CPVT_WordRange& PlaceRange) { @@ -918,12 +911,9 @@ void CPDF_VariableText::LinkLatterSection(const CPVT_WordPlace& place) { CPVT_WordPlace oldplace = AdjustLineHeader(place, true); if (CSection* pNextSection = m_SectionArray.GetAt(place.nSecIndex + 1)) { if (CSection* pSection = m_SectionArray.GetAt(oldplace.nSecIndex)) { - for (int32_t w = 0, sz = pNextSection->m_WordArray.GetSize(); w < sz; - w++) { - if (CPVT_WordInfo* pWord = pNextSection->m_WordArray.GetAt(w)) { - oldplace.nWordIndex++; - pSection->AddWord(oldplace, *pWord); - } + for (auto& pWord : pNextSection->m_WordArray) { + oldplace.nWordIndex++; + pSection->AddWord(oldplace, *pWord); } } delete pNextSection; @@ -943,21 +933,23 @@ void CPDF_VariableText::ClearWords(const CPVT_WordRange& PlaceRange) { } CPVT_WordPlace CPDF_VariableText::ClearLeftWord(const CPVT_WordPlace& place) { - if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) { - CPVT_WordPlace leftplace = GetPrevWordPlace(place); - if (leftplace != place) { - if (leftplace.nSecIndex != place.nSecIndex) { - if (pSection->m_WordArray.GetSize() == 0) - ClearEmptySection(place); - else - LinkLatterSection(leftplace); - } else { - pSection->ClearWord(place); - } - } - return leftplace; + CSection* pSection = m_SectionArray.GetAt(place.nSecIndex); + if (!pSection) + return place; + + CPVT_WordPlace leftplace = GetPrevWordPlace(place); + if (leftplace == place) + return place; + + if (leftplace.nSecIndex != place.nSecIndex) { + if (pSection->m_WordArray.empty()) + ClearEmptySection(place); + else + LinkLatterSection(leftplace); + } else { + pSection->ClearWord(place); } - return place; + return leftplace; } CPVT_WordPlace CPDF_VariableText::ClearRightWord(const CPVT_WordPlace& place) { diff --git a/core/fpdfdoc/csection.cpp b/core/fpdfdoc/csection.cpp index 0c7825585c..6198d780fd 100644 --- a/core/fpdfdoc/csection.cpp +++ b/core/fpdfdoc/csection.cpp @@ -15,25 +15,13 @@ CSection::CSection(CPDF_VariableText* pVT) : m_pVT(pVT) {} -CSection::~CSection() { - ResetAll(); -} +CSection::~CSection() {} void CSection::ResetAll() { - ResetWordArray(); - ResetLineArray(); -} - -void CSection::ResetLineArray() { + m_WordArray.clear(); m_LineArray.clear(); } -void CSection::ResetWordArray() { - for (int32_t i = 0, sz = m_WordArray.GetSize(); i < sz; i++) - delete m_WordArray.GetAt(i); - m_WordArray.RemoveAll(); -} - void CSection::ResetLinePlace() { int32_t i = 0; for (auto& pLine : m_LineArray) { @@ -44,13 +32,10 @@ void CSection::ResetLinePlace() { CPVT_WordPlace CSection::AddWord(const CPVT_WordPlace& place, const CPVT_WordInfo& wordinfo) { - CPVT_WordInfo* pWord = new CPVT_WordInfo(wordinfo); - int32_t nWordIndex = - pdfium::clamp(place.nWordIndex, 0, m_WordArray.GetSize()); - if (nWordIndex == m_WordArray.GetSize()) - m_WordArray.Add(pWord); - else - m_WordArray.InsertAt(nWordIndex, pWord); + int32_t nWordIndex = pdfium::clamp( + place.nWordIndex, 0, pdfium::CollectionSize(m_WordArray)); + m_WordArray.insert(m_WordArray.begin() + nWordIndex, + pdfium::MakeUnique(wordinfo)); return place; } @@ -202,54 +187,50 @@ CPVT_WordPlace CSection::SearchWordPlace(float fx, int32_t nRight = range.EndPos.nWordIndex + 1; int32_t nMid = (nLeft + nRight) / 2; while (nLeft < nRight) { - if (nMid == nLeft) { + if (nMid == nLeft) break; - } if (nMid == nRight) { nMid--; break; } - if (CPVT_WordInfo* pWord = m_WordArray.GetAt(nMid)) { - if (fx > - pWord->fWordX + m_pVT->GetWordWidth(*pWord) * VARIABLETEXT_HALF) { - nLeft = nMid; - nMid = (nLeft + nRight) / 2; - continue; - } else { - nRight = nMid; - nMid = (nLeft + nRight) / 2; - continue; - } - } else { + if (!pdfium::IndexInBounds(m_WordArray, nMid)) break; + CPVT_WordInfo* pWord = m_WordArray[nMid].get(); + if (fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * VARIABLETEXT_HALF) { + nLeft = nMid; + nMid = (nLeft + nRight) / 2; + continue; } + nRight = nMid; + nMid = (nLeft + nRight) / 2; } - if (CPVT_WordInfo* pWord = m_WordArray.GetAt(nMid)) { - if (fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * VARIABLETEXT_HALF) { + if (pdfium::IndexInBounds(m_WordArray, nMid)) { + CPVT_WordInfo* pWord = m_WordArray[nMid].get(); + if (fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * VARIABLETEXT_HALF) wordplace.nWordIndex = nMid; - } } return wordplace; } void CSection::ClearLeftWords(int32_t nWordIndex) { for (int32_t i = nWordIndex; i >= 0; i--) { - delete m_WordArray.GetAt(i); - m_WordArray.RemoveAt(i); + if (pdfium::IndexInBounds(m_WordArray, i)) + m_WordArray.erase(m_WordArray.begin() + i); } } void CSection::ClearRightWords(int32_t nWordIndex) { - for (int32_t i = m_WordArray.GetSize() - 1; i > nWordIndex; i--) { - delete m_WordArray.GetAt(i); - m_WordArray.RemoveAt(i); + int32_t sz = pdfium::CollectionSize(m_WordArray); + for (int32_t i = sz - 1; i > nWordIndex; i--) { + if (pdfium::IndexInBounds(m_WordArray, i)) + m_WordArray.erase(m_WordArray.begin() + i); } } void CSection::ClearMidWords(int32_t nBeginIndex, int32_t nEndIndex) { for (int32_t i = nEndIndex; i > nBeginIndex; i--) { - delete m_WordArray.GetAt(i); - m_WordArray.RemoveAt(i); + if (pdfium::IndexInBounds(m_WordArray, i)) + m_WordArray.erase(m_WordArray.begin() + i); } } @@ -266,11 +247,11 @@ void CSection::ClearWords(const CPVT_WordRange& PlaceRange) { } else if (PlaceRange.EndPos.WordCmp(SecEndPos) <= 0) { ClearLeftWords(PlaceRange.EndPos.nWordIndex); } else { - ResetWordArray(); + m_WordArray.clear(); } } void CSection::ClearWord(const CPVT_WordPlace& place) { - delete m_WordArray.GetAt(place.nWordIndex); - m_WordArray.RemoveAt(place.nWordIndex); + if (pdfium::IndexInBounds(m_WordArray, place.nWordIndex)) + m_WordArray.erase(m_WordArray.begin() + place.nWordIndex); } diff --git a/core/fpdfdoc/csection.h b/core/fpdfdoc/csection.h index 6907b3dc45..b465d1d63d 100644 --- a/core/fpdfdoc/csection.h +++ b/core/fpdfdoc/csection.h @@ -27,8 +27,6 @@ class CSection final { ~CSection(); void ResetAll(); - void ResetLineArray(); - void ResetWordArray(); void ResetLinePlace(); CPVT_WordPlace AddWord(const CPVT_WordPlace& place, const CPVT_WordInfo& wordinfo); @@ -50,7 +48,7 @@ class CSection final { CPVT_WordPlace SecPlace; CPVT_SectionInfo m_SecInfo; std::vector> m_LineArray; - CPVT_ArrayTemplate m_WordArray; + std::vector> m_WordArray; private: friend class CTypeset; diff --git a/core/fpdfdoc/ctypeset.cpp b/core/fpdfdoc/ctypeset.cpp index 34deb216b2..2e2f6c54a4 100644 --- a/core/fpdfdoc/ctypeset.cpp +++ b/core/fpdfdoc/ctypeset.cpp @@ -199,52 +199,58 @@ CPVT_FloatRect CTypeset::CharArray() { pLine->m_LineInfo.fLineX = fNodeWidth * VARIABLETEXT_HALF; break; case 1: - nStart = (m_pVT->m_nCharArray - m_pSection->m_WordArray.GetSize()) / 2; + nStart = (m_pVT->m_nCharArray - + pdfium::CollectionSize(m_pSection->m_WordArray)) / + 2; pLine->m_LineInfo.fLineX = fNodeWidth * nStart - fNodeWidth * VARIABLETEXT_HALF; break; case 2: - nStart = m_pVT->m_nCharArray - m_pSection->m_WordArray.GetSize(); + nStart = m_pVT->m_nCharArray - + pdfium::CollectionSize(m_pSection->m_WordArray); pLine->m_LineInfo.fLineX = fNodeWidth * nStart - fNodeWidth * VARIABLETEXT_HALF; break; } - for (int32_t w = 0, sz = m_pSection->m_WordArray.GetSize(); w < sz; w++) { + for (int32_t w = 0, + sz = pdfium::CollectionSize(m_pSection->m_WordArray); + w < sz; w++) { if (w >= m_pVT->m_nCharArray) break; float fNextWidth = 0; - if (CPVT_WordInfo* pNextWord = m_pSection->m_WordArray.GetAt(w + 1)) { + if (pdfium::IndexInBounds(m_pSection->m_WordArray, w + 1)) { + CPVT_WordInfo* pNextWord = m_pSection->m_WordArray[w + 1].get(); pNextWord->fWordTail = 0; fNextWidth = m_pVT->GetWordWidth(*pNextWord); } - if (CPVT_WordInfo* pWord = m_pSection->m_WordArray.GetAt(w)) { + CPVT_WordInfo* pWord = m_pSection->m_WordArray[w].get(); + pWord->fWordTail = 0; + float fWordWidth = m_pVT->GetWordWidth(*pWord); + float fWordAscent = m_pVT->GetWordAscent(*pWord); + float fWordDescent = m_pVT->GetWordDescent(*pWord); + x = (float)(fNodeWidth * (w + nStart + 0.5) - + fWordWidth * VARIABLETEXT_HALF); + pWord->fWordX = x; + pWord->fWordY = y; + if (w == 0) { + pLine->m_LineInfo.fLineX = x; + } + if (w != pdfium::CollectionSize(m_pSection->m_WordArray) - 1) { + pWord->fWordTail = + (fNodeWidth - (fWordWidth + fNextWidth) * VARIABLETEXT_HALF > 0 + ? fNodeWidth - (fWordWidth + fNextWidth) * VARIABLETEXT_HALF + : 0); + } else { pWord->fWordTail = 0; - float fWordWidth = m_pVT->GetWordWidth(*pWord); - float fWordAscent = m_pVT->GetWordAscent(*pWord); - float fWordDescent = m_pVT->GetWordDescent(*pWord); - x = (float)(fNodeWidth * (w + nStart + 0.5) - - fWordWidth * VARIABLETEXT_HALF); - pWord->fWordX = x; - pWord->fWordY = y; - if (w == 0) { - pLine->m_LineInfo.fLineX = x; - } - if (w != m_pSection->m_WordArray.GetSize() - 1) { - pWord->fWordTail = - (fNodeWidth - (fWordWidth + fNextWidth) * VARIABLETEXT_HALF > 0 - ? fNodeWidth - (fWordWidth + fNextWidth) * VARIABLETEXT_HALF - : 0); - } else { - pWord->fWordTail = 0; - } - x += fWordWidth; - fLineAscent = std::max(fLineAscent, fWordAscent); - fLineDescent = std::min(fLineDescent, fWordDescent); } + x += fWordWidth; + fLineAscent = std::max(fLineAscent, fWordAscent); + fLineDescent = std::min(fLineDescent, fWordDescent); } pLine->m_LineInfo.nBeginWordIndex = 0; - pLine->m_LineInfo.nEndWordIndex = m_pSection->m_WordArray.GetSize() - 1; + pLine->m_LineInfo.nEndWordIndex = + pdfium::CollectionSize(m_pSection->m_WordArray) - 1; pLine->m_LineInfo.fLineY = y; pLine->m_LineInfo.fLineWidth = x - pLine->m_LineInfo.fLineX; pLine->m_LineInfo.fLineAscent = fLineAscent; @@ -286,15 +292,16 @@ void CTypeset::SplitLines(bool bTypeset, float fFontSize) { float fTypesetWidth = std::max( m_pVT->GetPlateWidth() - m_pVT->GetLineIndent(m_pSection->m_SecInfo), 0.0f); - int32_t nTotalWords = m_pSection->m_WordArray.GetSize(); + int32_t nTotalWords = + pdfium::CollectionSize(m_pSection->m_WordArray); bool bOpened = false; if (nTotalWords > 0) { int32_t i = 0; while (i < nTotalWords) { - CPVT_WordInfo* pWord = m_pSection->m_WordArray.GetAt(i); + CPVT_WordInfo* pWord = m_pSection->m_WordArray[i].get(); CPVT_WordInfo* pOldWord = pWord; if (i > 0) { - pOldWord = m_pSection->m_WordArray.GetAt(i - 1); + pOldWord = m_pSection->m_WordArray[i - 1].get(); } if (pWord) { if (bTypeset) { @@ -462,7 +469,8 @@ void CTypeset::OutputLines() { pLine->m_LineInfo.fLineY = fPosY - fMinY; for (int32_t w = pLine->m_LineInfo.nBeginWordIndex; w <= pLine->m_LineInfo.nEndWordIndex; w++) { - if (CPVT_WordInfo* pWord = m_pSection->m_WordArray.GetAt(w)) { + if (pdfium::IndexInBounds(m_pSection->m_WordArray, w)) { + CPVT_WordInfo* pWord = m_pSection->m_WordArray[w].get(); pWord->fWordX = fPosX - fMinX; if (pWord->pWordProps) { switch (pWord->pWordProps->nScriptType) { -- cgit v1.2.3