oox/source/ppt/pptgraphicshapecontext.cxx | 8 +++++--- oox/source/ppt/pptshapecontext.cxx | 22 ++++++++++++++-------- sd/qa/unit/data/pptx/tdf163741.pptx |binary sd/qa/unit/import-tests2.cxx | 18 ++++++++++++++++++ 4 files changed, 37 insertions(+), 11 deletions(-)
New commits: commit b03cbc9a67091ce640adc0f23a87f06f83f8edd0 Author: Mohit Marathe <[email protected]> AuthorDate: Fri Feb 27 17:15:42 2026 +0530 Commit: Mohit Marathe <[email protected]> CommitDate: Mon Mar 2 17:54:30 2026 +0100 tdf#163741 pptx import: skip placeholder matching for idx=UINT32_MAX Placeholders with idx="4294967295" (SAL_MAX_UINT32) are sentinel values meaning "no specific placeholder link." Previously, getInteger() silently overflowed this to 0, causing the shape to wrongly match a layout placeholder and inherit incorrect text properties (e.g. 10pt instead of the expected 18pt from the master's bodyStyle). Parse idx as unsigned via getUnsigned() to detect the sentinel, then skip setSubTypeIndex(), findPlaceholderByIndex(), and findPlaceholder() entirely so the shape falls through to the master text style cascade. Signed-off-by: Mohit Marathe <[email protected]> Change-Id: Ib8b0c068720440695bffe25bc23d3f28406fea60 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200622 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/oox/source/ppt/pptgraphicshapecontext.cxx b/oox/source/ppt/pptgraphicshapecontext.cxx index 7d9fc0a2289d..b918c6b0e8b2 100644 --- a/oox/source/ppt/pptgraphicshapecontext.cxx +++ b/oox/source/ppt/pptgraphicshapecontext.cxx @@ -60,11 +60,13 @@ ContextHandlerRef PPTGraphicShapeContext::onCreateContext( sal_Int32 aElementTok mpShapePtr->setSubType( nSubType ); OUString sIdx( rAttribs.getStringDefaulted( XML_idx ) ); bool bHasIdx = !sIdx.isEmpty(); - sal_Int32 nIdx = sIdx.toInt32(); - if( rAttribs.hasAttribute( XML_idx ) ) + sal_uInt32 nUnsignedIdx = rAttribs.getUnsigned( XML_idx, 0 ); + bool bSkipPlaceholderLookup = (bHasIdx && nUnsignedIdx == SAL_MAX_UINT32); + sal_Int32 nIdx = static_cast<sal_Int32>(nUnsignedIdx); + if( rAttribs.hasAttribute( XML_idx ) && !bSkipPlaceholderLookup ) mpShapePtr->setSubTypeIndex( nIdx ); - if ( nSubType || bHasIdx ) + if ( (nSubType || bHasIdx) && !bSkipPlaceholderLookup ) { PPTShape* pPPTShapePtr = dynamic_cast< PPTShape* >( mpShapePtr.get() ); if ( pPPTShapePtr ) diff --git a/oox/source/ppt/pptshapecontext.cxx b/oox/source/ppt/pptshapecontext.cxx index 6caed1728d01..40ade6a2ca05 100644 --- a/oox/source/ppt/pptshapecontext.cxx +++ b/oox/source/ppt/pptshapecontext.cxx @@ -72,17 +72,23 @@ ContextHandlerRef PPTShapeContext::onCreateContext( sal_Int32 aElementToken, con mpShapePtr->setSubType( nSubType ); + bool bSkipPlaceholderLookup = false; if( rAttribs.hasAttribute( XML_idx ) ) { - sal_Int32 nSubTypeIndex = rAttribs.getInteger( XML_idx, 0 ); - mpShapePtr->setSubTypeIndex( nSubTypeIndex ); - - if(!oSubType.has_value() && pMasterPersist) + sal_uInt32 nUnsignedIdx = rAttribs.getUnsigned( XML_idx, 0 ); + bSkipPlaceholderLookup = (nUnsignedIdx == SAL_MAX_UINT32); + sal_Int32 nSubTypeIndex = static_cast<sal_Int32>(nUnsignedIdx); + if (!bSkipPlaceholderLookup) { - pTmpPlaceholder = PPTShape::findPlaceholderByIndex( nSubTypeIndex, pMasterPersist->getShapes()->getChildren() ); + mpShapePtr->setSubTypeIndex( nSubTypeIndex ); + + if(!oSubType.has_value() && pMasterPersist) + { + pTmpPlaceholder = PPTShape::findPlaceholderByIndex( nSubTypeIndex, pMasterPersist->getShapes()->getChildren() ); - if(pTmpPlaceholder) - nSubType = pTmpPlaceholder->getSubType(); // When we don't have type attribute on slide but have on slidelayout we have to use it instead of default type + if(pTmpPlaceholder) + nSubType = pTmpPlaceholder->getSubType(); // When we don't have type attribute on slide but have on slidelayout we have to use it instead of default type + } } } @@ -132,7 +138,7 @@ ContextHandlerRef PPTShapeContext::onCreateContext( sal_Int32 aElementToken, con default: break; } - if ( nFirstPlaceholder ) + if ( nFirstPlaceholder && !bSkipPlaceholderLookup ) { oox::drawingml::ShapePtr pPlaceholder; if ( eShapeLocation == Layout ) // for layout objects the referenced object can be found within the same shape tree diff --git a/sd/qa/unit/data/pptx/tdf163741.pptx b/sd/qa/unit/data/pptx/tdf163741.pptx new file mode 100644 index 000000000000..abbfa0b6a87b Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf163741.pptx differ diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx index 37f6a367949a..7945bff1b58a 100644 --- a/sd/qa/unit/import-tests2.cxx +++ b/sd/qa/unit/import-tests2.cxx @@ -2280,6 +2280,24 @@ CPPUNIT_TEST_FIXTURE(SdImportTest2, testTdf168109) } } +CPPUNIT_TEST_FIXTURE(SdImportTest2, testTdf163741) +{ + createSdImpressDoc("pptx/tdf163741.pptx"); + + // Shape "Shape 1" has <p:ph type="body" idx="4294967295"/>. + // idx=4294967295 (UINT32_MAX) is a sentinel meaning "no placeholder link". + // It must NOT match any layout placeholder; font size should come from + // the slide master's bodyStyle (18pt), not from a layout placeholder (10pt). + uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0)); + uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xShape)); + uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph)); + uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY_THROW); + + double fCharHeight = 0; + xPropSet->getPropertyValue(u"CharHeight"_ustr) >>= fCharHeight; + CPPUNIT_ASSERT_EQUAL(18.0, fCharHeight); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
