86e716e
From 0a646ae118e0a376481fc3cbc945031702b26c1a Mon Sep 17 00:00:00 2001
86e716e
From: Eike Rathke <erack@redhat.com>
86e716e
Date: Sat, 21 Jan 2012 01:15:02 +0100
86e716e
Subject: [PATCH 2/5] Resolves fdo#43725 crash on saving a file
86e716e
86e716e
+ Checks out-of-bounds accesses in
86e716e
  ScFormatRangeStyles::GetStyleNameIndex() and
86e716e
  ScRowFormatRanges::AddRange() and prevents crashes.
86e716e
- The real cause seems to be some style row/repeat miscalculation
86e716e
  elsewhere, further investigation would be necessary.
86e716e
86e716e
Signed-off-by: Norbert Thiebaud <nthiebaud@gmail.com>
86e716e
---
86e716e
 sc/source/filter/xml/XMLStylesExportHelper.cxx |   87 ++++++++++++++++++++----
86e716e
 1 files changed, 74 insertions(+), 13 deletions(-)
86e716e
86e716e
diff --git a/sc/source/filter/xml/XMLStylesExportHelper.cxx b/sc/source/filter/xml/XMLStylesExportHelper.cxx
86e716e
index 5ae0485..38d1523 100644
86e716e
--- a/sc/source/filter/xml/XMLStylesExportHelper.cxx
86e716e
+++ b/sc/source/filter/xml/XMLStylesExportHelper.cxx
86e716e
@@ -680,10 +680,35 @@ void ScRowFormatRanges::AddRange(ScMyRowFormatRange& rFormatRange,
86e716e
     const sal_Int32 nRow)
86e716e
 {
86e716e
     DBG_ASSERT(pRowDefaults, "no row defaults");
86e716e
+    if (!pRowDefaults)
86e716e
+        return;
86e716e
     DBG_ASSERT(pColDefaults, "no column defaults");
86e716e
+    if (!pColDefaults)
86e716e
+        return;
86e716e
+    sal_Int32 nPrevIndex;
86e716e
+    bool bPrevAutoStyle;
86e716e
+    OSL_ENSURE( static_cast<size_t>(nRow) < pRowDefaults->size(), "nRow out of bounds");
86e716e
+    if (!(static_cast<size_t>(nRow) < pRowDefaults->size()))
86e716e
+    {
86e716e
+        /* This is only to prevent out-of-bounds accesses, once reached here
86e716e
+         * there's something else going wrong, so FIXME there! */
86e716e
+        if (pRowDefaults->empty())
86e716e
+        {
86e716e
+            nPrevIndex = -1;
86e716e
+            bPrevAutoStyle = false;
86e716e
+        }
86e716e
+        else
86e716e
+        {
86e716e
+            nPrevIndex = (*pRowDefaults)[pRowDefaults->size()-1].nIndex;
86e716e
+            bPrevAutoStyle = (*pRowDefaults)[pRowDefaults->size()-1].bIsAutoStyle;
86e716e
+        }
86e716e
+    }
86e716e
+    else
86e716e
+    {
86e716e
+        nPrevIndex = (*pRowDefaults)[nRow].nIndex;
86e716e
+        bPrevAutoStyle = (*pRowDefaults)[nRow].bIsAutoStyle;
86e716e
+    }
86e716e
     sal_uInt32 nEnd (rFormatRange.nRepeatRows + nRow - 1);
86e716e
-    sal_Int32 nPrevIndex((*pRowDefaults)[nRow].nIndex);
86e716e
-    sal_Bool bPrevAutoStyle((*pRowDefaults)[nRow].bIsAutoStyle);
86e716e
     sal_uInt32 i(nRow + 1);
86e716e
     sal_Bool bReady(false);
86e716e
     while ((i < nEnd) && !bReady && (i < pRowDefaults->size()))
86e716e
@@ -700,12 +725,34 @@ void ScRowFormatRanges::AddRange(ScMyRowFormatRange& rFormatRange,
86e716e
         rFormatRange.nRepeatRows = i - nRow + 1;
86e716e
     if (nPrevIndex == -1)
86e716e
     {
86e716e
-        nPrevIndex = (*pColDefaults)[rFormatRange.nStartColumn].nIndex;
86e716e
-        bPrevAutoStyle = (*pColDefaults)[rFormatRange.nStartColumn].bIsAutoStyle;
86e716e
         sal_uInt32 nPrevStartCol(rFormatRange.nStartColumn);
86e716e
-        sal_uInt32 nRepeat((*pColDefaults)[rFormatRange.nStartColumn].nRepeat);
86e716e
-        nEnd = rFormatRange.nStartColumn + rFormatRange.nRepeatColumns;
86e716e
-        for(i = nPrevStartCol + nRepeat; i < nEnd; i += (*pColDefaults)[i].nRepeat)
86e716e
+        OSL_ENSURE( static_cast<size_t>(nPrevStartCol) < pColDefaults->size(), "nPrevStartCol out of bounds");
86e716e
+        sal_uInt32 nRepeat;
86e716e
+        if (static_cast<size_t>(nPrevStartCol) < pColDefaults->size())
86e716e
+        {
86e716e
+            nRepeat = (*pColDefaults)[nPrevStartCol].nRepeat;
86e716e
+            nPrevIndex = (*pColDefaults)[nPrevStartCol].nIndex;
86e716e
+            bPrevAutoStyle = (*pColDefaults)[nPrevStartCol].bIsAutoStyle;
86e716e
+        }
86e716e
+        else
86e716e
+        {
86e716e
+            /* Again, this is to prevent out-of-bounds accesses, so FIXME
86e716e
+             * elsewhere! */
86e716e
+            if (pColDefaults->empty())
86e716e
+            {
86e716e
+                nRepeat = 1;
86e716e
+                nPrevIndex = -1;
86e716e
+                bPrevAutoStyle = false;
86e716e
+            }
86e716e
+            else
86e716e
+            {
86e716e
+                nRepeat = (*pColDefaults)[pColDefaults->size()-1].nRepeat;
86e716e
+                nPrevIndex = (*pColDefaults)[pColDefaults->size()-1].nIndex;
86e716e
+                bPrevAutoStyle = (*pColDefaults)[pColDefaults->size()-1].bIsAutoStyle;
86e716e
+            }
86e716e
+        }
86e716e
+        nEnd = nPrevStartCol + rFormatRange.nRepeatColumns;
86e716e
+        for(i = nPrevStartCol + nRepeat; i < nEnd && i < pColDefaults->size(); i += (*pColDefaults)[i].nRepeat)
86e716e
         {
86e716e
             DBG_ASSERT(sal_uInt32(nPrevStartCol + nRepeat) <= nEnd, "something wents wrong");
86e716e
             if ((nPrevIndex != (*pColDefaults)[i].nIndex) ||
86e716e
@@ -924,6 +971,8 @@ sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable,
86e716e
     const sal_Int32 nColumn, const sal_Int32 nRow, sal_Bool& bIsAutoStyle) const
86e716e
 {
86e716e
     DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
86e716e
+    if (!(static_cast<size_t>(nTable) < aTables.size()))
86e716e
+        return -1;
86e716e
     ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
86e716e
     ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
86e716e
     ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());
86e716e
@@ -947,6 +996,8 @@ sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable, const s
86e716e
     sal_Bool& bIsAutoStyle, sal_Int32& nValidationIndex, sal_Int32& nNumberFormat, const sal_Int32 nRemoveBeforeRow)
86e716e
 {
86e716e
     DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
86e716e
+    if (!(static_cast<size_t>(nTable) < aTables.size()))
86e716e
+        return -1;
86e716e
     ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
86e716e
     ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
86e716e
     ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());
86e716e
@@ -960,7 +1011,10 @@ sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable, const s
86e716e
             bIsAutoStyle = aItr->bIsAutoStyle;
86e716e
             nValidationIndex = aItr->nValidationIndex;
86e716e
             nNumberFormat = aItr->nNumberFormat;
86e716e
-            if (((*pRowDefaults)[nRow].nIndex != -1))
86e716e
+            /* out-of-bounds is an error elsewhere, so FIXME there! */
86e716e
+            OSL_ENSURE( static_cast<size_t>(nRow) < pRowDefaults->size(), "nRow out of bounds");
86e716e
+            if (static_cast<size_t>(nRow) < pRowDefaults->size() &&
86e716e
+                    ((*pRowDefaults)[nRow].nIndex != -1))
86e716e
             {
86e716e
                 if (((*pRowDefaults)[nRow].nIndex == (*aItr).nStyleNameIndex) &&
86e716e
                     ((*pRowDefaults)[nRow].bIsAutoStyle == (*aItr).bIsAutoStyle))
86e716e
@@ -968,12 +1022,17 @@ sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable, const s
86e716e
                 else
86e716e
                     return (*aItr).nStyleNameIndex;
86e716e
             }
86e716e
-            else if (((*pColDefaults)[nColumn].nIndex != -1) &&
86e716e
-                ((*pColDefaults)[nColumn].nIndex == (*aItr).nStyleNameIndex) &&
86e716e
-                ((*pColDefaults)[nColumn].bIsAutoStyle == (*aItr).bIsAutoStyle))
86e716e
-                return -1;
86e716e
             else
86e716e
-                return (*aItr).nStyleNameIndex;
86e716e
+            {
86e716e
+                OSL_ENSURE( static_cast<size_t>(nColumn) < pColDefaults->size(), "nColumn out of bounds");
86e716e
+                if (static_cast<size_t>(nColumn) < pColDefaults->size() &&
86e716e
+                        ((*pColDefaults)[nColumn].nIndex != -1) &&
86e716e
+                        ((*pColDefaults)[nColumn].nIndex == (*aItr).nStyleNameIndex) &&
86e716e
+                        ((*pColDefaults)[nColumn].bIsAutoStyle == (*aItr).bIsAutoStyle))
86e716e
+                    return -1;
86e716e
+                else
86e716e
+                    return (*aItr).nStyleNameIndex;
86e716e
+            }
86e716e
         }
86e716e
         else
86e716e
         {
86e716e
@@ -991,6 +1050,8 @@ void ScFormatRangeStyles::GetFormatRanges(const sal_Int32 nStartColumn, const sa
86e716e
 {
86e716e
     sal_Int32 nTotalColumns(nEndColumn - nStartColumn + 1);
86e716e
     DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
86e716e
+    if (!(static_cast<size_t>(nTable) < aTables.size()))
86e716e
+        return;
86e716e
     ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
86e716e
     ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
86e716e
     ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());
86e716e
-- 
86e716e
1.7.7.6
86e716e