summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2018-01-15 22:29:31 +0100
committerAndras Timar <andras.timar@collabora.com>2019-08-22 12:33:04 +0200
commit6a099cc2817e2d5cf8cadd8b82c6d9c4c845b44e (patch)
tree68e3df4b397939dc28a39dee228de2d3fd7bb293
parent1962967fce22b735f340897c8f9ccbe7cc721652 (diff)
tdf#114536 sw: fix use-after-free in SwTextFormatter::MergeCharacterBorder()
SwTextFormatter::Underflow() truncated a line portion, which deletes the rest of the line portions, but left m_pFirstOfBorderMerge unchanged, leading to a crash when SwTextFormatter::MergeCharacterBorder() tried to access it. Fix the problem by updating the non-owning m_pFirstOfBorderMerge accordingly when truncating the line portion. (cherry picked from commit ecd855794b22c0f7e6fb2f362b566c4d9c5f624a) Conflicts: sw/qa/extras/uiwriter/uiwriter.cxx Reviewed-on: https://gerrit.libreoffice.org/47989 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com> (cherry picked from commit 968348dfe3f151ee41163006e7748777a0379e65) Change-Id: I5e445bbe2424d70d60c363fa4e3a00636e282325
-rw-r--r--sw/qa/extras/uiwriter/data/tdf114536.odtbin0 -> 13623 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx9
-rw-r--r--sw/source/core/text/itrform2.cxx13
3 files changed, 22 insertions, 0 deletions
diff --git a/sw/qa/extras/uiwriter/data/tdf114536.odt b/sw/qa/extras/uiwriter/data/tdf114536.odt
new file mode 100644
index 000000000000..4ad9c7f1f494
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf114536.odt
Binary files differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index d1211da8af61..eda6e56e9a8e 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -244,6 +244,7 @@ public:
void testTdf115013();
void testTdf115132();
void testTdf116403();
+ void testTdf114536();
CPPUNIT_TEST_SUITE(SwUiWriterTest);
CPPUNIT_TEST(testReplaceForward);
@@ -375,6 +376,7 @@ public:
CPPUNIT_TEST(testTdf115013);
CPPUNIT_TEST(testTdf115132);
CPPUNIT_TEST(testTdf116403);
+ CPPUNIT_TEST(testTdf114536);
CPPUNIT_TEST_SUITE_END();
private:
@@ -4619,6 +4621,13 @@ void SwUiWriterTest::testTdf107976()
CPPUNIT_ASSERT(!pTransferable2->GetShell());
}
+void SwUiWriterTest::testTdf114536()
+{
+ // This crashed in SwTextFormatter::MergeCharacterBorder() due to a
+ // use after free.
+ createDoc("tdf114536.odt");
+}
+
void SwUiWriterTest::testTdf113790()
{
SwDoc* pDoc = createDoc("tdf113790.docx");
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 4e315b731274..328f813a3807 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -273,6 +273,19 @@ SwLinePortion *SwTextFormatter::Underflow( SwTextFormatInfo &rInf )
pPor = m_pCurr;
}
}
+
+ // Make sure that m_pFirstOfBorderMerge does not point to a portion which
+ // will be deleted by Truncate() below.
+ SwLinePortion* pNext = pPor->GetPortion();
+ while (pNext)
+ {
+ if (pNext == m_pFirstOfBorderMerge)
+ {
+ m_pFirstOfBorderMerge = nullptr;
+ break;
+ }
+ pNext = pNext->GetPortion();
+ }
pPor->Truncate();
SwLinePortion *const pRest( rInf.GetRest() );
if (pRest && pRest->InFieldGrp() &&