sc/source/filter/html/htmlpars.cxx | 67 ++++++++++++++++++------------------- sc/source/filter/inc/htmlpars.hxx | 8 ++-- 2 files changed, 37 insertions(+), 38 deletions(-)
New commits: commit 4645391b56c32d59f241e66798f72183ad29ad13 Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Mon Mar 18 20:47:02 2024 +0000 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Tue Mar 19 09:41:55 2024 +0100 AddressSanitizer: container-overflow in initial sc html fuzzing Change-Id: I20d7baa6fd6fcb9c7d0019d7891a237dd721ef31 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164980 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx index 928674f31a3e..1e70163ddd82 100644 --- a/sc/source/filter/html/htmlpars.cxx +++ b/sc/source/filter/html/htmlpars.cxx @@ -737,12 +737,17 @@ void ScHTMLLayoutParser::SetWidths() MakeColNoRef( xLocalColOffset.get(), nOff, 0, 0, 0 ); } nTableWidth = static_cast<sal_uInt16>(xLocalColOffset->back() - xLocalColOffset->front()); + const auto nColsAvailable = xLocalColOffset->size(); for ( size_t i = nFirstTableCell, nListSize = maList.size(); i < nListSize; ++i ) { auto& pE = maList[ i ]; if ( pE->nTab == nTable ) { - pE->nOffset = static_cast<sal_uInt16>((*xLocalColOffset)[pE->nCol - nColCntStart]); + const size_t nColRequested = pE->nCol - nColCntStart; + if (nColRequested < nColsAvailable) + pE->nOffset = static_cast<sal_uInt16>((*xLocalColOffset)[nColRequested]); + else + SAL_WARN("sc", "missing information for column: " << nColRequested); pE->nWidth = 0; // to be recalculated later } } commit 79ccc9866aff73e953642ec2610438855ab0f088 Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Mon Mar 18 19:32:26 2024 +0000 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Tue Mar 19 09:41:47 2024 +0100 leaks in initial corpus for sc html import fuzzing Change-Id: Ia7a9d6b283dcf127dccf734fb45cf8ac3dde5478 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164978 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx index 846feda1ca85..928674f31a3e 100644 --- a/sc/source/filter/html/htmlpars.cxx +++ b/sc/source/filter/html/htmlpars.cxx @@ -304,7 +304,7 @@ ScHTMLLayoutParser::ScHTMLLayoutParser( aPageSize( aPageSizeP ), aBaseURL(std::move( _aBaseURL )), xLockedList( new ScRangeList ), - pLocalColOffset( new ScHTMLColOffset ), + xLocalColOffset( new ScHTMLColOffset ), nFirstTableCell(0), nTableLevel(0), nTable(0), @@ -320,20 +320,15 @@ ScHTMLLayoutParser::ScHTMLLayoutParser( bInCell( false ), bInTitle( false ) { - MakeColNoRef( pLocalColOffset, 0, 0, 0, 0 ); + MakeColNoRef( xLocalColOffset.get(), 0, 0, 0, 0 ); MakeColNoRef( &maColOffset, 0, 0, 0, 0 ); } ScHTMLLayoutParser::~ScHTMLLayoutParser() { - while ( !aTableStack.empty() ) - { - ScHTMLTableStackEntry * pS = aTableStack.top().get(); - if ( pS->pLocalColOffset != pLocalColOffset ) - delete pS->pLocalColOffset; + while (!aTableStack.empty()) aTableStack.pop(); - } - delete pLocalColOffset; + xLocalColOffset.reset(); if ( pTables ) { for( const auto& rEntry : *pTables) @@ -716,9 +711,9 @@ sal_uInt16 ScHTMLLayoutParser::GetWidth( const ScEEParseEntry* pE ) return pE->nWidth; sal_Int32 nTmp = std::min( static_cast<sal_Int32>( pE->nCol - nColCntStart + pE->nColOverlap), - static_cast<sal_Int32>( pLocalColOffset->size() - 1)); + static_cast<sal_Int32>( xLocalColOffset->size() - 1)); SCCOL nPos = (nTmp < 0 ? 0 : static_cast<SCCOL>(nTmp)); - sal_uInt16 nOff2 = static_cast<sal_uInt16>((*pLocalColOffset)[nPos]); + sal_uInt16 nOff2 = static_cast<sal_uInt16>((*xLocalColOffset)[nPos]); if ( pE->nOffset < nOff2 ) return nOff2 - pE->nOffset; return 0; @@ -732,22 +727,22 @@ void ScHTMLLayoutParser::SetWidths() SCCOL nColsPerRow = nMaxCol - nColCntStart; if ( nColsPerRow <= 0 ) nColsPerRow = 1; - if ( pLocalColOffset->size() <= 2 ) + if ( xLocalColOffset->size() <= 2 ) { // Only PageSize, there was no width setting sal_uInt16 nWidth = nTableWidth / static_cast<sal_uInt16>(nColsPerRow); sal_uInt16 nOff = nColOffsetStart; - pLocalColOffset->clear(); + xLocalColOffset->clear(); for ( nCol = 0; nCol <= nColsPerRow; ++nCol, nOff = nOff + nWidth ) { - MakeColNoRef( pLocalColOffset, nOff, 0, 0, 0 ); + MakeColNoRef( xLocalColOffset.get(), nOff, 0, 0, 0 ); } - nTableWidth = static_cast<sal_uInt16>(pLocalColOffset->back() - pLocalColOffset->front()); + nTableWidth = static_cast<sal_uInt16>(xLocalColOffset->back() - xLocalColOffset->front()); for ( size_t i = nFirstTableCell, nListSize = maList.size(); i < nListSize; ++i ) { auto& pE = maList[ i ]; if ( pE->nTab == nTable ) { - pE->nOffset = static_cast<sal_uInt16>((*pLocalColOffset)[pE->nCol - nColCntStart]); + pE->nOffset = static_cast<sal_uInt16>((*xLocalColOffset)[pE->nCol - nColCntStart]); pE->nWidth = 0; // to be recalculated later } } @@ -826,10 +821,10 @@ void ScHTMLLayoutParser::SetWidths() { pOffsets[nCol] = pOffsets[nCol-1] + pWidths[nCol-1]; } - pLocalColOffset->clear(); + xLocalColOffset->clear(); for ( nCol = 0; nCol <= nColsPerRow; nCol++ ) { - MakeColNoRef( pLocalColOffset, pOffsets[nCol], 0, 0, 0 ); + MakeColNoRef( xLocalColOffset.get(), pOffsets[nCol], 0, 0, 0 ); } nTableWidth = pOffsets[nColsPerRow] - pOffsets[0]; @@ -852,15 +847,15 @@ void ScHTMLLayoutParser::SetWidths() } } } - if ( !pLocalColOffset->empty() ) + if ( !xLocalColOffset->empty() ) { - sal_uInt16 nMax = static_cast<sal_uInt16>(pLocalColOffset->back()); + sal_uInt16 nMax = static_cast<sal_uInt16>(xLocalColOffset->back()); if ( aPageSize.Width() < nMax ) aPageSize.setWidth( nMax ); if (nTableLevel == 0) { // Local table is very outer table, create missing offsets. - for (auto it = pLocalColOffset->begin(); it != pLocalColOffset->end(); ++it) + for (auto it = xLocalColOffset->begin(); it != xLocalColOffset->end(); ++it) { // Only exact offsets, do not use MakeColNoRef(). maColOffset.insert(*it); @@ -894,15 +889,15 @@ void ScHTMLLayoutParser::Colonize( ScEEParseEntry* pE ) if ( nCol < pE->nCol ) { // Replaced nCol = pE->nCol - nColCntStart; - SCCOL nCount = static_cast<SCCOL>(pLocalColOffset->size()); + SCCOL nCount = static_cast<SCCOL>(xLocalColOffset->size()); if ( nCol < nCount ) - nColOffset = static_cast<sal_uInt16>((*pLocalColOffset)[nCol]); + nColOffset = static_cast<sal_uInt16>((*xLocalColOffset)[nCol]); else - nColOffset = static_cast<sal_uInt16>((*pLocalColOffset)[nCount - 1]); + nColOffset = static_cast<sal_uInt16>((*xLocalColOffset)[nCount - 1]); } pE->nOffset = nColOffset; sal_uInt16 nWidth = GetWidth( pE ); - MakeCol( pLocalColOffset, pE->nOffset, nWidth, nOffsetTolerance, nOffsetTolerance ); + MakeCol( xLocalColOffset.get(), pE->nOffset, nWidth, nOffsetTolerance, nOffsetTolerance ); if ( pE->nWidth ) pE->nWidth = nWidth; nColOffset = pE->nOffset + nWidth; @@ -1146,7 +1141,7 @@ void ScHTMLLayoutParser::TableOn( HtmlImportInfo* pInfo ) sal_uInt16 nTmpColOffset = nColOffset; // Will be changed in Colonize() Colonize(mxActEntry.get()); aTableStack.push( std::make_unique<ScHTMLTableStackEntry>( - mxActEntry, xLockedList, pLocalColOffset, nFirstTableCell, + mxActEntry, xLockedList, xLocalColOffset, nFirstTableCell, nRowCnt, nColCntStart, nMaxCol, nTable, nTableWidth, nColOffset, nColOffsetStart, bFirstRow ) ); @@ -1202,7 +1197,7 @@ void ScHTMLLayoutParser::TableOn( HtmlImportInfo* pInfo ) NextRow( pInfo ); } aTableStack.push( std::make_unique<ScHTMLTableStackEntry>( - mxActEntry, xLockedList, pLocalColOffset, nFirstTableCell, + mxActEntry, xLockedList, xLocalColOffset, nFirstTableCell, nRowCnt, nColCntStart, nMaxCol, nTable, nTableWidth, nColOffset, nColOffsetStart, bFirstRow ) ); @@ -1235,8 +1230,8 @@ void ScHTMLLayoutParser::TableOn( HtmlImportInfo* pInfo ) bFirstRow = true; nFirstTableCell = maList.size(); - pLocalColOffset = new ScHTMLColOffset; - MakeColNoRef( pLocalColOffset, nColOffsetStart, 0, 0, 0 ); + xLocalColOffset.reset(new ScHTMLColOffset); + MakeColNoRef( xLocalColOffset.get(), nColOffsetStart, 0, 0, 0 ); } void ScHTMLLayoutParser::TableOff( const HtmlImportInfo* pInfo ) @@ -1352,7 +1347,7 @@ void ScHTMLLayoutParser::TableOff( const HtmlImportInfo* pInfo ) { sal_uInt16 nOldOffset = pE->nOffset + pE->nWidth; sal_uInt16 nNewOffset = pE->nOffset + nTableWidth; - ModifyOffset( pS->pLocalColOffset, nOldOffset, nNewOffset, nOffsetTolerance ); + ModifyOffset( pS->xLocalColOffset.get(), nOldOffset, nNewOffset, nOffsetTolerance ); sal_uInt16 nTmp = nNewOffset - pE->nOffset - pE->nWidth; pE->nWidth = nNewOffset - pE->nOffset; pS->nTableWidth = pS->nTableWidth + nTmp; @@ -1371,7 +1366,7 @@ void ScHTMLLayoutParser::TableOff( const HtmlImportInfo* pInfo ) nColOffsetStart = pS->nColOffsetStart; bFirstRow = pS->bFirstRow; xLockedList = pS->xLockedList; - pLocalColOffset = pS->pLocalColOffset; + xLocalColOffset = pS->xLocalColOffset; // mxActEntry is kept around if a table is started in the same row // (anything's possible in HTML); will be deleted by CloseEntry mxActEntry = pE; @@ -1387,8 +1382,7 @@ void ScHTMLLayoutParser::TableOff( const HtmlImportInfo* pInfo ) if ( !aTableStack.empty() ) { ScHTMLTableStackEntry* pS = aTableStack.top().get(); - delete pLocalColOffset; - pLocalColOffset = pS->pLocalColOffset; + xLocalColOffset = std::move(pS->xLocalColOffset); aTableStack.pop(); } } @@ -1501,7 +1495,7 @@ void ScHTMLLayoutParser::ColOn( HtmlImportInfo* pInfo ) if( rOption.GetToken() == HtmlOptionId::WIDTH ) { sal_uInt16 nVal = GetWidthPixel( rOption ); - MakeCol( pLocalColOffset, nColOffset, nVal, 0, 0 ); + MakeCol( xLocalColOffset.get(), nColOffset, nVal, 0, 0 ); nColOffset = nColOffset + nVal; } } diff --git a/sc/source/filter/inc/htmlpars.hxx b/sc/source/filter/inc/htmlpars.hxx index 1ac9aa000225..7043c9176182 100644 --- a/sc/source/filter/inc/htmlpars.hxx +++ b/sc/source/filter/inc/htmlpars.hxx @@ -102,7 +102,7 @@ struct ScHTMLTableStackEntry { ScRangeListRef xLockedList; std::shared_ptr<ScEEParseEntry> xCellEntry; - ScHTMLColOffset* pLocalColOffset; + std::shared_ptr<ScHTMLColOffset> xLocalColOffset; sal_uLong nFirstTableCell; SCROW nRowCnt; SCCOL nColCntStart; @@ -113,14 +113,14 @@ struct ScHTMLTableStackEntry sal_uInt16 nColOffsetStart; bool bFirstRow; ScHTMLTableStackEntry( std::shared_ptr<ScEEParseEntry> xE, - ScRangeListRef xL, ScHTMLColOffset* pTO, + ScRangeListRef xL, std::shared_ptr<ScHTMLColOffset> xTO, sal_uLong nFTC, SCROW nRow, SCCOL nStart, SCCOL nMax, sal_uInt16 nTab, sal_uInt16 nTW, sal_uInt16 nCO, sal_uInt16 nCOS, bool bFR ) : xLockedList(std::move( xL )), xCellEntry(std::move(xE)), - pLocalColOffset( pTO ), + xLocalColOffset( std::move(xTO) ), nFirstTableCell( nFTC ), nRowCnt( nRow ), nColCntStart( nStart ), nMaxCol( nMax ), @@ -162,7 +162,7 @@ private: ScRangeListRef xLockedList; // per table std::unique_ptr<OuterMap> pTables; ScHTMLColOffset maColOffset; - ScHTMLColOffset* pLocalColOffset; // per table + std::shared_ptr<ScHTMLColOffset> xLocalColOffset; // per table sal_uLong nFirstTableCell; // per table short nTableLevel; sal_uInt16 nTable;