summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2022-08-14 20:46:49 +0100
committerCaolán McNamara <caolan.mcnamara@collabora.com>2023-06-28 17:31:47 +0200
commita62973bd350f2e9d372765ed99eed423efa0d39f (patch)
tree3d63178ba2ee5e744cc3fcf7cab823cd854aeb07
parent64dbb50e028e56c224a55affbc17277da40b659e (diff)
ofz#49713 Heap-use-after-free
the dtor of ScAttrArray where the std::vector<ScAttrEntry> ends up will call ScDocumentPool::Remove on each entries pPattern, assuming that a matching ScDocumentPool::Put was called on each, something that is elided if we just do a simply copy here. probably a problem since: commit dddee125cc32f1ad5228e598a7de04e9654e65c1 Date: Thu Mar 10 15:03:25 2022 +0100 load ods/xlsx with full row attributes without allocating all columns Change-Id: I3a5e2e3fa4d40343f30f9eefbabd1579d8a97e02 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138262 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com> (cherry picked from commit 6c81a09e3ef239a2d7a991d00fe3620a67298b99) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153584 Tested-by: Caolán McNamara <caolan.mcnamara@collabora.com> Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
-rw-r--r--sc/qa/unit/data/xls/pass/ofz49713-1.xlsbin0 -> 33 bytes
-rw-r--r--sc/source/core/data/table2.cxx18
2 files changed, 16 insertions, 2 deletions
diff --git a/sc/qa/unit/data/xls/pass/ofz49713-1.xls b/sc/qa/unit/data/xls/pass/ofz49713-1.xls
new file mode 100644
index 000000000000..b32574013e95
--- /dev/null
+++ b/sc/qa/unit/data/xls/pass/ofz49713-1.xls
Binary files differ
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index a7d073c89966..3ed331fbc908 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -2908,6 +2908,20 @@ void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol,
CreateColumnIfNotExists(i).ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray, pIsChanged);
}
+namespace
+{
+ std::vector<ScAttrEntry> duplicateScAttrEntries(ScDocument& rDocument, const std::vector<ScAttrEntry>& rOrigData)
+ {
+ std::vector<ScAttrEntry> aData(rOrigData);
+ for (size_t nIdx = 0; nIdx < aData.size(); ++nIdx)
+ {
+ ScPatternAttr aNewPattern(*aData[nIdx].pPattern);
+ aData[nIdx].pPattern = &rDocument.GetPool()->Put(aNewPattern);
+ }
+ return aData;
+ }
+}
+
void ScTable::SetAttrEntries( SCCOL nStartCol, SCCOL nEndCol, std::vector<ScAttrEntry> && vNewData)
{
if (!ValidCol(nStartCol) || !ValidCol(nEndCol))
@@ -2919,7 +2933,7 @@ void ScTable::SetAttrEntries( SCCOL nStartCol, SCCOL nEndCol, std::vector<ScAttr
// If we would like set all columns to same attrs, then change only attrs for not existing columns
nEndCol = aCol.size() - 1;
for (SCCOL i = nStartCol; i <= nEndCol; i++)
- aCol[i].SetAttrEntries( std::vector<ScAttrEntry>(vNewData));
+ aCol[i].SetAttrEntries(duplicateScAttrEntries(rDocument, vNewData));
aDefaultColData.SetAttrEntries(std::move(vNewData));
}
else
@@ -2932,7 +2946,7 @@ void ScTable::SetAttrEntries( SCCOL nStartCol, SCCOL nEndCol, std::vector<ScAttr
{
CreateColumnIfNotExists( nEndCol );
for (SCCOL i = nStartCol; i < nEndCol; i++) // all but last need a copy
- aCol[i].SetAttrEntries( std::vector<ScAttrEntry>(vNewData));
+ aCol[i].SetAttrEntries(duplicateScAttrEntries(rDocument, vNewData));
aCol[nEndCol].SetAttrEntries( std::move(vNewData));
}
}