Kaydet (Commit) 1ba1cbe4 authored tarafından Takeshi Abe's avatar Takeshi Abe Kaydeden (comit) Eike Rathke

tdf#91425 CRASH - Calc Insert Columns Left

This fix is a SCCOL variant of:

commit c66d1b9fcc2244b4fd8940f17ebf4e772f09c84e
Author: Kohei Yoshida <kyoshida@novell.com>
Date:   Thu May 5 00:23:25 2011 -0400

    fdo#36406: Let's not use invalidated iterators.

    std::set::erase(iterator) call invalidates the iterator of the erased
    element.  We better not use it after the erase() call.  Since the number
    of manual breaks should not be high enough to cause a performance
    bottleneck under normal usage, a safer linear copy should just be fine.

    Now, I'm not sure if this indeed is the cause of the erroneous amount
    of manual breaks in the test document, but I didn't see any other likely
    spot.

Change-Id: I0c2e8f738949776aa7f8ea5528e2c0eeb9351c16
Reviewed-on: https://gerrit.libreoffice.org/16063Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
Tested-by: 's avatarEike Rathke <erack@redhat.com>
üst 57e7f486
...@@ -295,18 +295,17 @@ void ScTable::InsertCol( ...@@ -295,18 +295,17 @@ void ScTable::InsertCol(
if (!maColManualBreaks.empty()) if (!maColManualBreaks.empty())
{ {
std::set<SCCOL>::reverse_iterator rit = maColManualBreaks.rbegin(); // Copy all breaks up to nStartCol (non-inclusive).
while (rit != maColManualBreaks.rend()) ::std::set<SCCOL>::iterator itr1 = maColManualBreaks.lower_bound(nStartCol);
{ ::std::set<SCCOL> aNewBreaks(maColManualBreaks.begin(), itr1);
SCCOL nCol = *rit;
if (nCol < nStartCol) // Copy all breaks from nStartCol (inclusive) to the last element,
break; // while // but add nSize to each value.
else ::std::set<SCCOL>::iterator itr2 = maColManualBreaks.end();
{ for (; itr1 != itr2; ++itr1)
maColManualBreaks.erase( (++rit).base()); aNewBreaks.insert(static_cast<SCCOL>(*itr1 + nSize));
maColManualBreaks.insert( static_cast<SCCOL>( nCol + nSize));
} maColManualBreaks.swap(aNewBreaks);
}
} }
} }
...@@ -376,14 +375,21 @@ void ScTable::DeleteCol( ...@@ -376,14 +375,21 @@ void ScTable::DeleteCol(
if (!maColManualBreaks.empty()) if (!maColManualBreaks.empty())
{ {
std::set<SCCOL>::iterator it = maColManualBreaks.upper_bound( static_cast<SCCOL>( nStartCol + nSize - 1)); // Erase all manual breaks between nStartCol and nStartCol + nSize - 1 (inclusive).
maColManualBreaks.erase( maColManualBreaks.lower_bound( nStartCol), it); std::set<SCCOL>::iterator itr1 = maColManualBreaks.lower_bound(nStartCol);
while (it != maColManualBreaks.end()) std::set<SCCOL>::iterator itr2 = maColManualBreaks.upper_bound(static_cast<SCCOL>(nStartCol + nSize - 1));
{ maColManualBreaks.erase(itr1, itr2);
SCCOL nCol = *it;
maColManualBreaks.erase( it++); // Copy all breaks from the 1st element up to nStartCol to the new container.
maColManualBreaks.insert( static_cast<SCCOL>( nCol - nSize)); itr1 = maColManualBreaks.lower_bound(nStartCol);
} ::std::set<SCCOL> aNewBreaks(maColManualBreaks.begin(), itr1);
// Copy all breaks from nStartCol to the last element, but subtract each value by nSize.
itr2 = maColManualBreaks.end();
for (; itr1 != itr2; ++itr1)
aNewBreaks.insert(static_cast<SCCOL>(*itr1 - nSize));
maColManualBreaks.swap(aNewBreaks);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment