sd: fix crash setting IsEmptyPresentationObject twice

Making a presentation object empty took the style for its prompt from the first
paragraph of the text it holds, without checking that it holds any: a graphic or
an OLE one never does, and making an object non-empty removes what text it had.

There is no message to quote - SdXShape::SetEmptyPresObj dereferences a null
OutlinerParaObject and the process goes down where it stands. To reach it in a
build without this fix, open a document whose slide holds an empty picture
placeholder, such as sd/qa/unit/data/pptx/tdfpictureplaceholder.pptx, and run in
Basic:

    oShape = ThisComponent.DrawPages(0).getByIndex(0)
    oShape.IsEmptyPresentationObject = False
    oShape.IsEmptyPresentationObject = True

Which way the prompt runs was taken from the text as well, so an object without
any got a horizontal one; it answers for that itself now.

Signed-off-by: Mike Kaganski <mike.kaganski@collabora.com>
Change-Id: Ie5ba7ee52e1e9a2131dbd09e1df4c773ea52431c
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/9304
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit a8df64888cad38c406929cd5a63960cdb8fdc545)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/210325
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
Mike Kaganski
2026-09-01 19:52:01 +02:00
committed by Xisco Fauli
parent 84c8ca6fd5
commit 3d01685a4f
2 changed files with 31 additions and 3 deletions
+21
View File
@@ -107,6 +107,7 @@ public:
void testDuplicateAndMove();
void testApiXDrawPageDuplicator();
void testApiXMasterPagesSupplier();
void testEmptyPresObjSetOnObjectWithoutText();
CPPUNIT_TEST_SUITE(SdMiscTest);
CPPUNIT_TEST(testTdf99396_UndoCellVerticalAlignment);
@@ -139,6 +140,7 @@ public:
CPPUNIT_TEST(testDuplicateAndMove);
CPPUNIT_TEST(testApiXDrawPageDuplicator);
CPPUNIT_TEST(testApiXMasterPagesSupplier);
CPPUNIT_TEST(testEmptyPresObjSetOnObjectWithoutText);
CPPUNIT_TEST_SUITE_END();
};
@@ -1367,6 +1369,25 @@ void SdMiscTest::testApiXMasterPagesSupplier()
CPPUNIT_ASSERT(xMasterPages->getCount() >= 1);
}
void SdMiscTest::testEmptyPresObjSetOnObjectWithoutText()
{
// Given an empty picture placeholder, which holds no outliner text at all:
createSdImpressDoc("pptx/tdfpictureplaceholder.pptx");
uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0));
bool bEmpty = false;
CPPUNIT_ASSERT(xShape->getPropertyValue(u"IsEmptyPresentationObject"_ustr) >>= bEmpty);
CPPUNIT_ASSERT(bEmpty);
// Then saying it is not empty and empty again must go through. Setting it back read the
// object's text to take a style from it without checking that there is any, so this crashed -
// a macro can reach it, and so can anything else that sets the property twice.
xShape->setPropertyValue(u"IsEmptyPresentationObject"_ustr, uno::Any(false));
xShape->setPropertyValue(u"IsEmptyPresentationObject"_ustr, uno::Any(true));
CPPUNIT_ASSERT(xShape->getPropertyValue(u"IsEmptyPresentationObject"_ustr) >>= bEmpty);
CPPUNIT_ASSERT(bEmpty);
}
CPPUNIT_TEST_SUITE_REGISTRATION(SdMiscTest);
CPPUNIT_PLUGIN_IMPLEMENT();
+10 -3
View File
@@ -944,9 +944,16 @@ void SdXShape::SetEmptyPresObj(bool bEmpty)
if( pPage == nullptr )
break;
OutlinerParaObject* pOutlinerParaObject = pObj->GetOutlinerParaObject();
pOutliner->SetText( *pOutlinerParaObject );
const bool bVertical = pOutliner->IsVertical();
// There may be no text to take the style from: a graphic or OLE presentation object
// never holds any, and emptying an object removes what it had. Which way the prompt
// runs is then the object's own answer.
auto pTextObj = DynCastSdrTextObj( pObj );
bool bVertical = pTextObj && pTextObj->IsVerticalWriting();
if (OutlinerParaObject* pOutlinerParaObject = pObj->GetOutlinerParaObject())
{
pOutliner->SetText( *pOutlinerParaObject );
bVertical = pOutliner->IsVertical();
}
pOutliner->Clear();
pOutliner->SetVertical( bVertical );