Pick a better type for the GetAttrib nAttr parameter

...which indexes into a std::vector.  To avoid the blemish of accompanying
std::size_t variables potentially getting decremented past zero (even though
that would be technically OK and not UB), rework some accompanying code to avoid
that.

Change-Id: Ie1ab2d079a7d8d34fceda1da2d31fa6a8c4fad6c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134255
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
Stephan Bergmann
2022-05-12 14:42:37 +02:00
parent c7d80d229a
commit eac2e7520d
4 changed files with 36 additions and 26 deletions

View File

@@ -30,6 +30,7 @@
#include <tools/lineend.hxx> #include <tools/lineend.hxx>
#include <o3tl/typed_flags_set.hxx> #include <o3tl/typed_flags_set.hxx>
#include <cstddef>
#include <memory> #include <memory>
#include <string_view> #include <string_view>
#include <vector> #include <vector>
@@ -809,9 +810,9 @@ public:
static OUString GetSepStr( LineEnd eEnd ); static OUString GetSepStr( LineEnd eEnd );
}; };
inline EditCharAttrib* GetAttrib(CharAttribList::AttribsType& rAttribs, sal_Int32 nAttr) inline EditCharAttrib* GetAttrib(CharAttribList::AttribsType& rAttribs, std::size_t nAttr)
{ {
return (nAttr < static_cast<sal_Int32>(rAttribs.size())) ? rAttribs[nAttr].get() : nullptr; return (nAttr < rAttribs.size()) ? rAttribs[nAttr].get() : nullptr;
} }
#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG

View File

@@ -59,6 +59,7 @@
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <cstddef>
#include <limits> #include <limits>
#include <memory> #include <memory>
#include <set> #include <set>
@@ -1215,7 +1216,7 @@ void ContentNode::ExpandAttribs( sal_Int32 nIndex, sal_Int32 nNew, SfxItemPool&
bool bResort = false; bool bResort = false;
bool bExpandedEmptyAtIndexNull = false; bool bExpandedEmptyAtIndexNull = false;
sal_Int32 nAttr = 0; std::size_t nAttr = 0;
CharAttribList::AttribsType& rAttribs = aCharAttribList.GetAttribs(); CharAttribList::AttribsType& rAttribs = aCharAttribList.GetAttribs();
EditCharAttrib* pAttrib = GetAttrib(rAttribs, nAttr); EditCharAttrib* pAttrib = GetAttrib(rAttribs, nAttr);
while ( pAttrib ) while ( pAttrib )
@@ -1280,7 +1281,7 @@ void ContentNode::ExpandAttribs( sal_Int32 nIndex, sal_Int32 nNew, SfxItemPool&
{ {
// Check if this kind of attribute was empty and expanded here... // Check if this kind of attribute was empty and expanded here...
sal_uInt16 nW = pAttrib->GetItem()->Which(); sal_uInt16 nW = pAttrib->GetItem()->Which();
for ( sal_Int32 nA = 0; nA < nAttr; nA++ ) for ( std::size_t nA = 0; nA < nAttr; nA++ )
{ {
const EditCharAttrib& r = *aCharAttribList.GetAttribs()[nA]; const EditCharAttrib& r = *aCharAttribList.GetAttribs()[nA];
if ( ( r.GetStart() == 0 ) && ( r.GetItem()->Which() == nW ) ) if ( ( r.GetStart() == 0 ) && ( r.GetItem()->Which() == nW ) )
@@ -1318,9 +1319,11 @@ void ContentNode::ExpandAttribs( sal_Int32 nIndex, sal_Int32 nNew, SfxItemPool&
bResort = true; bResort = true;
rItemPool.Remove( *pAttrib->GetItem() ); rItemPool.Remove( *pAttrib->GetItem() );
rAttribs.erase(rAttribs.begin()+nAttr); rAttribs.erase(rAttribs.begin()+nAttr);
--nAttr;
} }
++nAttr; else
{
++nAttr;
}
pAttrib = GetAttrib(rAttribs, nAttr); pAttrib = GetAttrib(rAttribs, nAttr);
} }
@@ -1352,7 +1355,7 @@ void ContentNode::CollapseAttribs( sal_Int32 nIndex, sal_Int32 nDeleted, SfxItem
bool bResort = false; bool bResort = false;
sal_Int32 nEndChanges = nIndex+nDeleted; sal_Int32 nEndChanges = nIndex+nDeleted;
sal_Int32 nAttr = 0; std::size_t nAttr = 0;
CharAttribList::AttribsType& rAttribs = aCharAttribList.GetAttribs(); CharAttribList::AttribsType& rAttribs = aCharAttribList.GetAttribs();
EditCharAttrib* pAttrib = GetAttrib(rAttribs, nAttr); EditCharAttrib* pAttrib = GetAttrib(rAttribs, nAttr);
while ( pAttrib ) while ( pAttrib )
@@ -1412,12 +1415,14 @@ void ContentNode::CollapseAttribs( sal_Int32 nIndex, sal_Int32 nDeleted, SfxItem
bResort = true; bResort = true;
rItemPool.Remove( *pAttrib->GetItem() ); rItemPool.Remove( *pAttrib->GetItem() );
rAttribs.erase(rAttribs.begin()+nAttr); rAttribs.erase(rAttribs.begin()+nAttr);
nAttr--;
} }
else if ( pAttrib->IsEmpty() ) else
aCharAttribList.SetHasEmptyAttribs(true); {
if ( pAttrib->IsEmpty() )
aCharAttribList.SetHasEmptyAttribs(true);
nAttr++;
}
nAttr++;
pAttrib = GetAttrib(rAttribs, nAttr); pAttrib = GetAttrib(rAttribs, nAttr);
} }
@@ -1443,7 +1448,7 @@ void ContentNode::CopyAndCutAttribs( ContentNode* pPrevNode, SfxItemPool& rPool,
sal_Int32 nCut = pPrevNode->Len(); sal_Int32 nCut = pPrevNode->Len();
sal_Int32 nAttr = 0; std::size_t nAttr = 0;
CharAttribList::AttribsType& rPrevAttribs = pPrevNode->GetCharAttribs().GetAttribs(); CharAttribList::AttribsType& rPrevAttribs = pPrevNode->GetCharAttribs().GetAttribs();
EditCharAttrib* pAttrib = GetAttrib(rPrevAttribs, nAttr); EditCharAttrib* pAttrib = GetAttrib(rPrevAttribs, nAttr);
while ( pAttrib ) while ( pAttrib )
@@ -1451,7 +1456,7 @@ void ContentNode::CopyAndCutAttribs( ContentNode* pPrevNode, SfxItemPool& rPool,
if ( pAttrib->GetEnd() < nCut ) if ( pAttrib->GetEnd() < nCut )
{ {
// remain unchanged... // remain unchanged...
; nAttr++;
} }
else if ( pAttrib->GetEnd() == nCut ) else if ( pAttrib->GetEnd() == nCut )
{ {
@@ -1462,6 +1467,7 @@ void ContentNode::CopyAndCutAttribs( ContentNode* pPrevNode, SfxItemPool& rPool,
assert(pNewAttrib); assert(pNewAttrib);
aCharAttribList.InsertAttrib( pNewAttrib ); aCharAttribList.InsertAttrib( pNewAttrib );
} }
nAttr++;
} }
else if ( pAttrib->IsInside( nCut ) || ( !nCut && !pAttrib->GetStart() && !pAttrib->IsFeature() ) ) else if ( pAttrib->IsInside( nCut ) || ( !nCut && !pAttrib->GetStart() && !pAttrib->IsFeature() ) )
{ {
@@ -1471,6 +1477,7 @@ void ContentNode::CopyAndCutAttribs( ContentNode* pPrevNode, SfxItemPool& rPool,
assert(pNewAttrib); assert(pNewAttrib);
aCharAttribList.InsertAttrib( pNewAttrib ); aCharAttribList.InsertAttrib( pNewAttrib );
pAttrib->GetEnd() = nCut; pAttrib->GetEnd() = nCut;
nAttr++;
} }
else else
{ {
@@ -1479,9 +1486,7 @@ void ContentNode::CopyAndCutAttribs( ContentNode* pPrevNode, SfxItemPool& rPool,
aCharAttribList.InsertAttrib(it->release()); aCharAttribList.InsertAttrib(it->release());
rPrevAttribs.erase(it); rPrevAttribs.erase(it);
pAttrib->MoveBackward( nCut ); pAttrib->MoveBackward( nCut );
nAttr--;
} }
nAttr++;
pAttrib = GetAttrib(rPrevAttribs, nAttr); pAttrib = GetAttrib(rPrevAttribs, nAttr);
} }
@@ -1502,7 +1507,7 @@ void ContentNode::AppendAttribs( ContentNode* pNextNode )
CharAttribList::DbgCheckAttribs(pNextNode->aCharAttribList); CharAttribList::DbgCheckAttribs(pNextNode->aCharAttribList);
#endif #endif
sal_Int32 nAttr = 0; std::size_t nAttr = 0;
CharAttribList::AttribsType& rNextAttribs = pNextNode->GetCharAttribs().GetAttribs(); CharAttribList::AttribsType& rNextAttribs = pNextNode->GetCharAttribs().GetAttribs();
EditCharAttrib* pAttrib = GetAttrib(rNextAttribs, nAttr); EditCharAttrib* pAttrib = GetAttrib(rNextAttribs, nAttr);
while ( pAttrib ) while ( pAttrib )
@@ -1512,10 +1517,11 @@ void ContentNode::AppendAttribs( ContentNode* pNextNode )
if ( ( pAttrib->GetStart() == 0 ) && ( !pAttrib->IsFeature() ) ) if ( ( pAttrib->GetStart() == 0 ) && ( !pAttrib->IsFeature() ) )
{ {
// Attributes can possibly be summarized as: // Attributes can possibly be summarized as:
sal_Int32 nTmpAttr = 0; std::size_t nTmpAttr = 0;
EditCharAttrib* pTmpAttrib = GetAttrib( aCharAttribList.GetAttribs(), nTmpAttr ); EditCharAttrib* pTmpAttrib = GetAttrib( aCharAttribList.GetAttribs(), nTmpAttr );
while ( !bMelted && pTmpAttrib ) while ( !bMelted && pTmpAttrib )
{ {
++nTmpAttr;
if ( pTmpAttrib->GetEnd() == nNewStart ) if ( pTmpAttrib->GetEnd() == nNewStart )
{ {
if (pTmpAttrib->Which() == pAttrib->Which()) if (pTmpAttrib->Which() == pAttrib->Which())
@@ -1532,12 +1538,11 @@ void ContentNode::AppendAttribs( ContentNode* pNextNode )
} }
else if (0 == pTmpAttrib->GetLen()) else if (0 == pTmpAttrib->GetLen())
{ {
--nTmpAttr; // to cancel earlier increment...
aCharAttribList.Remove(nTmpAttr); aCharAttribList.Remove(nTmpAttr);
--nTmpAttr; // to cancel later increment...
} }
} }
} }
++nTmpAttr;
pTmpAttrib = GetAttrib( aCharAttribList.GetAttribs(), nTmpAttr ); pTmpAttrib = GetAttrib( aCharAttribList.GetAttribs(), nTmpAttr );
} }
} }
@@ -2425,7 +2430,7 @@ bool EditDoc::RemoveAttribs( ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEn
#endif #endif
// iterate over the attributes ... // iterate over the attributes ...
sal_Int32 nAttr = 0; std::size_t nAttr = 0;
CharAttribList::AttribsType& rAttribs = pNode->GetCharAttribs().GetAttribs(); CharAttribList::AttribsType& rAttribs = pNode->GetCharAttribs().GetAttribs();
EditCharAttrib* pAttr = GetAttrib(rAttribs, nAttr); EditCharAttrib* pAttr = GetAttrib(rAttribs, nAttr);
while ( pAttr ) while ( pAttr )
@@ -2505,9 +2510,11 @@ bool EditDoc::RemoveAttribs( ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEn
DBG_ASSERT( !pAttr->IsFeature(), "RemoveAttribs: Remove a feature?!" ); DBG_ASSERT( !pAttr->IsFeature(), "RemoveAttribs: Remove a feature?!" );
GetItemPool().Remove( *pAttr->GetItem() ); GetItemPool().Remove( *pAttr->GetItem() );
rAttribs.erase(rAttribs.begin()+nAttr); rAttribs.erase(rAttribs.begin()+nAttr);
nAttr--;
} }
nAttr++; else
{
nAttr++;
}
pAttr = GetAttrib(rAttribs, nAttr); pAttr = GetAttrib(rAttribs, nAttr);
} }
@@ -2585,7 +2592,7 @@ void EditDoc::FindAttribs( ContentNode* pNode, sal_Int32 nStartPos, sal_Int32 nE
assert(pNode); assert(pNode);
DBG_ASSERT( nStartPos <= nEndPos, "Invalid region!" ); DBG_ASSERT( nStartPos <= nEndPos, "Invalid region!" );
sal_uInt16 nAttr = 0; std::size_t nAttr = 0;
EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr ); EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
// No Selection... // No Selection...
if ( nStartPos == nEndPos ) if ( nStartPos == nEndPos )

View File

@@ -69,6 +69,7 @@
#include <o3tl/sorted_vector.hxx> #include <o3tl/sorted_vector.hxx>
#include <osl/diagnose.h> #include <osl/diagnose.h>
#include <comphelper/string.hxx> #include <comphelper/string.hxx>
#include <cstddef>
#include <memory> #include <memory>
#include <set> #include <set>
@@ -2412,7 +2413,7 @@ void ImpEditEngine::CreateTextPortions( ParaPortion* pParaPortion, sal_Int32& rS
o3tl::sorted_vector< sal_Int32 > aPositions; o3tl::sorted_vector< sal_Int32 > aPositions;
aPositions.insert( 0 ); aPositions.insert( 0 );
for (sal_uInt16 nAttr = 0;; ++nAttr) for (std::size_t nAttr = 0;; ++nAttr)
{ {
// Insert Start and End into the Array... // Insert Start and End into the Array...
// The Insert method does not allow for duplicate values... // The Insert method does not allow for duplicate values...

View File

@@ -72,6 +72,7 @@
#include <svtools/rtfkeywd.hxx> #include <svtools/rtfkeywd.hxx>
#include <editeng/edtdlg.hxx> #include <editeng/edtdlg.hxx>
#include <cstddef>
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@@ -247,7 +248,7 @@ bool ImpEditEngine::WriteItemListAsRTF( ItemList& rLst, SvStream& rOutput, sal_I
static void lcl_FindValidAttribs( ItemList& rLst, ContentNode* pNode, sal_Int32 nIndex, sal_uInt16 nScriptType ) static void lcl_FindValidAttribs( ItemList& rLst, ContentNode* pNode, sal_Int32 nIndex, sal_uInt16 nScriptType )
{ {
sal_uInt16 nAttr = 0; std::size_t nAttr = 0;
EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr ); EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
while ( pAttr && ( pAttr->GetStart() <= nIndex ) ) while ( pAttr && ( pAttr->GetStart() <= nIndex ) )
{ {
@@ -1040,7 +1041,7 @@ std::unique_ptr<EditTextObject> ImpEditEngine::CreateTextObject( EditSelection a
auto& rCAttriblist = pC->GetCharAttribs(); auto& rCAttriblist = pC->GetCharAttribs();
// and the Attribute... // and the Attribute...
sal_uInt16 nAttr = 0; std::size_t nAttr = 0;
EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr ); EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
while ( pAttr ) while ( pAttr )
{ {