Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


Hi,

Attached is a backport to 3-4 of
http://cgit.freedesktop.org/libreoffice/core/commit/?id=6198fcd7064180a0bf8a6d67f63f784610aa9ba8

Please review and cherry-pick to 3-4, this resolves
https://bugs.freedesktop.org/show_bug.cgi?id=43725 crash when saving
document after having added a sheet

  Eike

-- 
LibreOffice Calc developer. Number formatter stricken i18n transpositionizer.
GnuPG key 0x293C05FD : 997A 4C60 CE41 0149 0DB3  9E96 2F1A D073 293C 05FD
From: Eike Rathke <erack@redhat.com>
Subject: [PATCH] Resolves fdo#43725 crash on saving a file
Date: Sat, 21 Jan 2012 01:15:02 +0100

+ Checks out-of-bounds accesses in
  ScFormatRangeStyles::GetStyleNameIndex() and
  ScRowFormatRanges::AddRange() and prevents crashes.
- The real cause seems to be some style row/repeat miscalculation
  elsewhere, further investigation would be necessary.
---

 sc/source/filter/xml/XMLStylesExportHelper.cxx |   87 ++++++++++++++++++++----
 1 files changed, 74 insertions(+), 13 deletions(-)

diff --git a/sc/source/filter/xml/XMLStylesExportHelper.cxx 
b/sc/source/filter/xml/XMLStylesExportHelper.cxx
index 5ae0485..38d1523 100644
--- a/sc/source/filter/xml/XMLStylesExportHelper.cxx
+++ b/sc/source/filter/xml/XMLStylesExportHelper.cxx
@@ -680,10 +680,35 @@ void ScRowFormatRanges::AddRange(ScMyRowFormatRange& rFormatRange,
     const sal_Int32 nRow)
 {
     DBG_ASSERT(pRowDefaults, "no row defaults");
+    if (!pRowDefaults)
+        return;
     DBG_ASSERT(pColDefaults, "no column defaults");
+    if (!pColDefaults)
+        return;
+    sal_Int32 nPrevIndex;
+    bool bPrevAutoStyle;
+    OSL_ENSURE( static_cast<size_t>(nRow) < pRowDefaults->size(), "nRow out of bounds");
+    if (!(static_cast<size_t>(nRow) < pRowDefaults->size()))
+    {
+        /* This is only to prevent out-of-bounds accesses, once reached here
+         * there's something else going wrong, so FIXME there! */
+        if (pRowDefaults->empty())
+        {
+            nPrevIndex = -1;
+            bPrevAutoStyle = false;
+        }
+        else
+        {
+            nPrevIndex = (*pRowDefaults)[pRowDefaults->size()-1].nIndex;
+            bPrevAutoStyle = (*pRowDefaults)[pRowDefaults->size()-1].bIsAutoStyle;
+        }
+    }
+    else
+    {
+        nPrevIndex = (*pRowDefaults)[nRow].nIndex;
+        bPrevAutoStyle = (*pRowDefaults)[nRow].bIsAutoStyle;
+    }
     sal_uInt32 nEnd (rFormatRange.nRepeatRows + nRow - 1);
-    sal_Int32 nPrevIndex((*pRowDefaults)[nRow].nIndex);
-    sal_Bool bPrevAutoStyle((*pRowDefaults)[nRow].bIsAutoStyle);
     sal_uInt32 i(nRow + 1);
     sal_Bool bReady(false);
     while ((i < nEnd) && !bReady && (i < pRowDefaults->size()))
@@ -700,12 +725,34 @@ void ScRowFormatRanges::AddRange(ScMyRowFormatRange& rFormatRange,
         rFormatRange.nRepeatRows = i - nRow + 1;
     if (nPrevIndex == -1)
     {
-        nPrevIndex = (*pColDefaults)[rFormatRange.nStartColumn].nIndex;
-        bPrevAutoStyle = (*pColDefaults)[rFormatRange.nStartColumn].bIsAutoStyle;
         sal_uInt32 nPrevStartCol(rFormatRange.nStartColumn);
-        sal_uInt32 nRepeat((*pColDefaults)[rFormatRange.nStartColumn].nRepeat);
-        nEnd = rFormatRange.nStartColumn + rFormatRange.nRepeatColumns;
-        for(i = nPrevStartCol + nRepeat; i < nEnd; i += (*pColDefaults)[i].nRepeat)
+        OSL_ENSURE( static_cast<size_t>(nPrevStartCol) < pColDefaults->size(), "nPrevStartCol out 
of bounds");
+        sal_uInt32 nRepeat;
+        if (static_cast<size_t>(nPrevStartCol) < pColDefaults->size())
+        {
+            nRepeat = (*pColDefaults)[nPrevStartCol].nRepeat;
+            nPrevIndex = (*pColDefaults)[nPrevStartCol].nIndex;
+            bPrevAutoStyle = (*pColDefaults)[nPrevStartCol].bIsAutoStyle;
+        }
+        else
+        {
+            /* Again, this is to prevent out-of-bounds accesses, so FIXME
+             * elsewhere! */
+            if (pColDefaults->empty())
+            {
+                nRepeat = 1;
+                nPrevIndex = -1;
+                bPrevAutoStyle = false;
+            }
+            else
+            {
+                nRepeat = (*pColDefaults)[pColDefaults->size()-1].nRepeat;
+                nPrevIndex = (*pColDefaults)[pColDefaults->size()-1].nIndex;
+                bPrevAutoStyle = (*pColDefaults)[pColDefaults->size()-1].bIsAutoStyle;
+            }
+        }
+        nEnd = nPrevStartCol + rFormatRange.nRepeatColumns;
+        for(i = nPrevStartCol + nRepeat; i < nEnd && i < pColDefaults->size(); i += 
(*pColDefaults)[i].nRepeat)
         {
             DBG_ASSERT(sal_uInt32(nPrevStartCol + nRepeat) <= nEnd, "something wents wrong");
             if ((nPrevIndex != (*pColDefaults)[i].nIndex) ||
@@ -924,6 +971,8 @@ sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable,
     const sal_Int32 nColumn, const sal_Int32 nRow, sal_Bool& bIsAutoStyle) const
 {
     DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+    if (!(static_cast<size_t>(nTable) < aTables.size()))
+        return -1;
     ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
     ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
     ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());
@@ -947,6 +996,8 @@ sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable, const s
     sal_Bool& bIsAutoStyle, sal_Int32& nValidationIndex, sal_Int32& nNumberFormat, const sal_Int32 
nRemoveBeforeRow)
 {
     DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+    if (!(static_cast<size_t>(nTable) < aTables.size()))
+        return -1;
     ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
     ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
     ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());
@@ -960,7 +1011,10 @@ sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable, 
const s
             bIsAutoStyle = aItr->bIsAutoStyle;
             nValidationIndex = aItr->nValidationIndex;
             nNumberFormat = aItr->nNumberFormat;
-            if (((*pRowDefaults)[nRow].nIndex != -1))
+            /* out-of-bounds is an error elsewhere, so FIXME there! */
+            OSL_ENSURE( static_cast<size_t>(nRow) < pRowDefaults->size(), "nRow out of bounds");
+            if (static_cast<size_t>(nRow) < pRowDefaults->size() &&
+                    ((*pRowDefaults)[nRow].nIndex != -1))
             {
                 if (((*pRowDefaults)[nRow].nIndex == (*aItr).nStyleNameIndex) &&
                     ((*pRowDefaults)[nRow].bIsAutoStyle == (*aItr).bIsAutoStyle))
@@ -968,12 +1022,17 @@ sal_Int32 ScFormatRangeStyles::GetStyleNameIndex(const sal_Int32 nTable, 
const s
                 else
                     return (*aItr).nStyleNameIndex;
             }
-            else if (((*pColDefaults)[nColumn].nIndex != -1) &&
-                ((*pColDefaults)[nColumn].nIndex == (*aItr).nStyleNameIndex) &&
-                ((*pColDefaults)[nColumn].bIsAutoStyle == (*aItr).bIsAutoStyle))
-                return -1;
             else
-                return (*aItr).nStyleNameIndex;
+            {
+                OSL_ENSURE( static_cast<size_t>(nColumn) < pColDefaults->size(), "nColumn out of 
bounds");
+                if (static_cast<size_t>(nColumn) < pColDefaults->size() &&
+                        ((*pColDefaults)[nColumn].nIndex != -1) &&
+                        ((*pColDefaults)[nColumn].nIndex == (*aItr).nStyleNameIndex) &&
+                        ((*pColDefaults)[nColumn].bIsAutoStyle == (*aItr).bIsAutoStyle))
+                    return -1;
+                else
+                    return (*aItr).nStyleNameIndex;
+            }
         }
         else
         {
@@ -991,6 +1050,8 @@ void ScFormatRangeStyles::GetFormatRanges(const sal_Int32 nStartColumn, const 
sa
 {
     sal_Int32 nTotalColumns(nEndColumn - nStartColumn + 1);
     DBG_ASSERT(static_cast<size_t>(nTable) < aTables.size(), "wrong table");
+    if (!(static_cast<size_t>(nTable) < aTables.size()))
+        return;
     ScMyFormatRangeAddresses* pFormatRanges(aTables[nTable]);
     ScMyFormatRangeAddresses::iterator aItr(pFormatRanges->begin());
     ScMyFormatRangeAddresses::iterator aEndItr(pFormatRanges->end());


Attachment: pgphl8pYNdG8y.pgp
Description: PGP signature


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.