diff options
author | Caolán McNamara <caolanm@redhat.com> | 2022-08-14 20:46:49 +0100 |
---|---|---|
committer | Caolán McNamara <caolan.mcnamara@collabora.com> | 2023-06-28 17:31:47 +0200 |
commit | a62973bd350f2e9d372765ed99eed423efa0d39f (patch) | |
tree | 3d63178ba2ee5e744cc3fcf7cab823cd854aeb07 | |
parent | 64dbb50e028e56c224a55affbc17277da40b659e (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.xls | bin | 0 -> 33 bytes | |||
-rw-r--r-- | sc/source/core/data/table2.cxx | 18 |
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 Binary files differnew file mode 100644 index 000000000000..b32574013e95 --- /dev/null +++ b/sc/qa/unit/data/xls/pass/ofz49713-1.xls 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)); } } |