handle broken row ranges in excel import

LIBREOFFICE-39G76603.xlsx from crashtesting has broken data cause
assertion failures about the ranges being sorted (because the ranges
overlap and StyleRowRangeComp needs and assumes that they do not).
Changing the std::unique() call to remove ranges that compare equal
(which is not the same as being equal, due to how StyleRowRangeComp
compares) and sorting again seems to drop all problematic ranges.
(I'm not adding the problematic file to tests as loading it takes
a lot of time.)

Change-Id: If6ac94959a649a641d02fd703d33edddbdf0fb85
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131637
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
This commit is contained in:
Luboš Luňák 2022-03-15 21:48:34 +01:00
parent 1fa4665331
commit ad1f6e6229
2 changed files with 9 additions and 8 deletions

View file

@ -206,13 +206,6 @@ private:
return lhs.mnEndRow<rhs.mnStartRow;
}
};
struct StyleRowRangeCompEqual
{
bool operator() (const RowRangeStyle& lhs, const RowRangeStyle& rhs) const
{
return lhs.mnStartRow==rhs.mnStartRow && lhs.mnEndRow == rhs.mnEndRow;
}
};
typedef ::o3tl::sorted_vector< RowRangeStyle, StyleRowRangeComp > RowStyles;
typedef ::std::map< sal_Int32, RowStyles > ColStyles;
typedef ::std::vector< RowRangeStyle > TmpRowStyles;

View file

@ -373,7 +373,15 @@ void SheetDataBuffer::addColXfStyles()
{
TmpRowStyles& s = rowStyles.second;
std::sort( s.begin(), s.end(), StyleRowRangeComp());
s.erase( std::unique( s.begin(), s.end(), StyleRowRangeCompEqual()), s.end());
s.erase( std::unique( s.begin(), s.end(),
[](const RowRangeStyle& lhs, const RowRangeStyle& rhs)
// Synthetize operator== from operator < . Do not create an actual operator==
// as operator< is somewhat specific (see StyleRowRangeComp).
{ return !StyleRowRangeComp()(lhs,rhs) && !StyleRowRangeComp()(rhs,lhs); } ),
s.end());
// Broken documents may have overlapping ranges that cause problems, re-sort again if needed.
if(!std::is_sorted(s.begin(), s.end(), StyleRowRangeComp()))
std::sort( s.begin(), s.end(), StyleRowRangeComp());
maStylesPerColumn[ rowStyles.first ].insert_sorted_unique_vector( std::move( s ));
}
}