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:
committed by
Xisco Fauli
parent
84c8ca6fd5
commit
3d01685a4f
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user