summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2017-02-17 14:10:37 +0100
committerKohei Yoshida <libreoffice@kohei.us>2017-02-22 13:36:28 +0000
commit092026853d073f7e24988e0cebe24e4312b45b9b (patch)
treedb5f85eeb9157bf2fa5fba455877e7e6af283966
parente0f2340927f5c7f734a4d4774badf729cafc1386 (diff)
Resolves: tdf#105858 check SC_DPOUT_MAXLEVELS to prevent crash
Backported. This is a combination of 2 commits. Resolves: tdf#105858 check nDataCount<SC_DPOUT_MAXLEVELS to prevent crash (cherry picked from commit 9bdf971b0202c6d55d88e61861b251459de9586b) more counts<SC_DPOUT_MAXLEVELS to check, tdf#105858 related Also for row, column and page field arrays. (cherry picked from commit 7fbdd8b7d3741d55b229977f9e6d6213af5fa542) 1dccdf139af778a2c0dc550be0b573c984256a2d Change-Id: If9084543a0a191d08da37b5b8a187bce46440871 Reviewed-on: https://gerrit.libreoffice.org/34372 Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com> Reviewed-by: Kohei Yoshida <libreoffice@kohei.us> Tested-by: Kohei Yoshida <libreoffice@kohei.us>
-rw-r--r--sc/source/core/data/dpoutput.cxx112
1 files changed, 68 insertions, 44 deletions
diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx
index d62739effd55..09b005cf1795 100644
--- a/sc/source/core/data/dpoutput.cxx
+++ b/sc/source/core/data/dpoutput.cxx
@@ -343,9 +343,10 @@ void lcl_FillNumberFormats( sal_uInt32*& rFormats, long& rCount,
OUString aDataNames[SC_DPOUT_MAXLEVELS];
sal_uInt32 nDataFormats[SC_DPOUT_MAXLEVELS];
- long nDataCount = 0;
- long nDimCount = xDims->getCount();
- for (long nDim=0; nDim<nDimCount; nDim++)
+ size_t nDataCount = 0;
+ sal_Int32 nDimCount = xDims->getCount();
+ sal_Int32 nDim = 0;
+ for ( ; nDim < nDimCount && nDataCount < SC_DPOUT_MAXLEVELS; nDim++)
{
uno::Reference<uno::XInterface> xDim =
ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
@@ -368,6 +369,8 @@ void lcl_FillNumberFormats( sal_uInt32*& rFormats, long& rCount,
}
}
}
+ SAL_WARN_IF( nDim < nDimCount && nDataCount == SC_DPOUT_MAXLEVELS, "sc.core",
+ "lcl_FillNumberFormats - may have lost an output level due to SC_DPOUT_MAXLEVELS=" << SC_DPOUT_MAXLEVELS);
if (!nDataCount)
return;
@@ -393,7 +396,7 @@ void lcl_FillNumberFormats( sal_uInt32*& rFormats, long& rCount,
aName = pArray[nPos].Name;
sal_uInt32 nFormat = 0;
- for (long i=0; i<nDataCount; i++)
+ for (size_t i=0; i<nDataCount; i++)
if (aName == aDataNames[i]) //TODO: search more efficiently?
{
nFormat = nDataFormats[i];
@@ -605,50 +608,71 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
switch ( eDimOrient )
{
case sheet::DataPilotFieldOrientation_COLUMN:
- pColFields[nColFieldCount].nDim = nDim;
- pColFields[nColFieldCount].nHier = nHierarchy;
- pColFields[nColFieldCount].nLevel = nLev;
- pColFields[nColFieldCount].nDimPos = nDimPos;
- pColFields[nColFieldCount].aResult = xLevRes->getResults();
- pColFields[nColFieldCount].mnSrcNumFmt = nNumFmt;
- pColFields[nColFieldCount].maName = aName;
- pColFields[nColFieldCount].maCaption= aCaption;
- pColFields[nColFieldCount].mbHasHiddenMember = bHasHiddenMember;
- pColFields[nColFieldCount].mbDataLayout = bIsDataLayout;
- if (!lcl_MemberEmpty(pColFields[nColFieldCount].aResult))
- ++nColFieldCount;
- break;
+ if (nColFieldCount < SC_DPOUT_MAXLEVELS)
+ {
+ pColFields[nColFieldCount].nDim = nDim;
+ pColFields[nColFieldCount].nHier = nHierarchy;
+ pColFields[nColFieldCount].nLevel = nLev;
+ pColFields[nColFieldCount].nDimPos = nDimPos;
+ pColFields[nColFieldCount].aResult = xLevRes->getResults();
+ pColFields[nColFieldCount].mnSrcNumFmt = nNumFmt;
+ pColFields[nColFieldCount].maName = aName;
+ pColFields[nColFieldCount].maCaption= aCaption;
+ pColFields[nColFieldCount].mbHasHiddenMember = bHasHiddenMember;
+ pColFields[nColFieldCount].mbDataLayout = bIsDataLayout;
+ if (!lcl_MemberEmpty(pColFields[nColFieldCount].aResult))
+ ++nColFieldCount;
+ }
+ else
+ {
+ SAL_WARN("sc.core","ScDPOutput - nColFieldCount already at SC_DPOUT_MAXLEVELS=" << SC_DPOUT_MAXLEVELS);
+ }
+ break;
case sheet::DataPilotFieldOrientation_ROW:
- pRowFields[nRowFieldCount].nDim = nDim;
- pRowFields[nRowFieldCount].nHier = nHierarchy;
- pRowFields[nRowFieldCount].nLevel = nLev;
- pRowFields[nRowFieldCount].nDimPos = nDimPos;
- pRowFields[nRowFieldCount].aResult = xLevRes->getResults();
- pRowFields[nRowFieldCount].mnSrcNumFmt = nNumFmt;
- pRowFields[nRowFieldCount].maName = aName;
- pRowFields[nRowFieldCount].maCaption= aCaption;
- pRowFields[nRowFieldCount].mbHasHiddenMember = bHasHiddenMember;
- pRowFields[nRowFieldCount].mbDataLayout = bIsDataLayout;
- if (!lcl_MemberEmpty(pRowFields[nRowFieldCount].aResult))
+ if (nRowFieldCount < SC_DPOUT_MAXLEVELS)
{
- ++nRowFieldCount;
- bRowFieldHasMember = true;
+ pRowFields[nRowFieldCount].nDim = nDim;
+ pRowFields[nRowFieldCount].nHier = nHierarchy;
+ pRowFields[nRowFieldCount].nLevel = nLev;
+ pRowFields[nRowFieldCount].nDimPos = nDimPos;
+ pRowFields[nRowFieldCount].aResult = xLevRes->getResults();
+ pRowFields[nRowFieldCount].mnSrcNumFmt = nNumFmt;
+ pRowFields[nRowFieldCount].maName = aName;
+ pRowFields[nRowFieldCount].maCaption= aCaption;
+ pRowFields[nRowFieldCount].mbHasHiddenMember = bHasHiddenMember;
+ pRowFields[nRowFieldCount].mbDataLayout = bIsDataLayout;
+ if (!lcl_MemberEmpty(pRowFields[nRowFieldCount].aResult))
+ {
+ ++nRowFieldCount;
+ bRowFieldHasMember = true;
+ }
}
- break;
+ else
+ {
+ SAL_WARN("sc.core","ScDPOutput - nRowFieldCount already at SC_DPOUT_MAXLEVELS=" << SC_DPOUT_MAXLEVELS);
+ }
+ break;
case sheet::DataPilotFieldOrientation_PAGE:
- pPageFields[nPageFieldCount].nDim = nDim;
- pPageFields[nPageFieldCount].nHier = nHierarchy;
- pPageFields[nPageFieldCount].nLevel = nLev;
- pPageFields[nPageFieldCount].nDimPos = nDimPos;
- pPageFields[nPageFieldCount].aResult = getVisiblePageMembersAsResults(xLevel);
- pPageFields[nPageFieldCount].mnSrcNumFmt = nNumFmt;
- pPageFields[nPageFieldCount].maName = aName;
- pPageFields[nPageFieldCount].maCaption= aCaption;
- pPageFields[nPageFieldCount].mbHasHiddenMember = bHasHiddenMember;
- pPageFields[nPageFieldCount].mbPageDim = true;
- // no check on results for page fields
- ++nPageFieldCount;
- break;
+ if (nPageFieldCount < SC_DPOUT_MAXLEVELS)
+ {
+ pPageFields[nPageFieldCount].nDim = nDim;
+ pPageFields[nPageFieldCount].nHier = nHierarchy;
+ pPageFields[nPageFieldCount].nLevel = nLev;
+ pPageFields[nPageFieldCount].nDimPos = nDimPos;
+ pPageFields[nPageFieldCount].aResult = getVisiblePageMembersAsResults(xLevel);
+ pPageFields[nPageFieldCount].mnSrcNumFmt = nNumFmt;
+ pPageFields[nPageFieldCount].maName = aName;
+ pPageFields[nPageFieldCount].maCaption= aCaption;
+ pPageFields[nPageFieldCount].mbHasHiddenMember = bHasHiddenMember;
+ pPageFields[nPageFieldCount].mbPageDim = true;
+ // no check on results for page fields
+ ++nPageFieldCount;
+ }
+ else
+ {
+ SAL_WARN("sc.core","ScDPOutput - nPageFieldCount already at SC_DPOUT_MAXLEVELS=" << SC_DPOUT_MAXLEVELS);
+ }
+ break;
default:
{
// added to avoid warnings