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 95082cb874dff5da131b5ef5031c288bc3bed3cf
Author:     Mohit Marathe <[email protected]>
AuthorDate: Fri Feb 27 17:15:42 2026 +0530
Commit:     Mohit Marathe <[email protected]>
CommitDate: Tue Mar 3 04:53:33 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]>
    (cherry picked from commit 0e7ccd35b978c92e3eb13882553cadc2e182fcf6)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200843

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 543dcc155726..7f86b4620613 100644
--- a/sd/qa/unit/import-tests2.cxx
+++ b/sd/qa/unit/import-tests2.cxx
@@ -2338,6 +2338,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: */

Reply via email to