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;

Reply via email to