package/source/xstor/owriteablestream.cxx    |   19 +++++++++++++++++++
 package/source/xstor/owriteablestream.hxx    |    5 ++++-
 sw/qa/extras/uiwriter/data/embeddedPPTX.docx |binary
 sw/qa/extras/uiwriter/uiwriter9.cxx          |    8 ++++++++
 4 files changed, 31 insertions(+), 1 deletion(-)

New commits:
commit 9c1b1dd020576392b469d6bcec2b64b3c4aadff0
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sat Jun 14 00:35:37 2025 +0500
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Jun 16 11:07:16 2025 +0200

    tdf#167006: OWriteStream needs to implement comphelper::ByteReader
    
    A crash seen with this call stack:
    
      package2.dll!ByteGrabber::ByteGrabber(const 
com::sun::star::uno::Reference<com::sun::star::io::XInputStream> & xIstream) 
Line 44++
      package2.dll!ZipFile::ZipFile(rtl::Reference<comphelper::RefCountedMutex> 
aMutexHolder, const 
com::sun::star::uno::Reference<com::sun::star::io::XInputStream> & xInput, 
com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> 
xContext, bool bInitialise, bool bForceRecovery, ZipFile::Checks checks) Line 
92++
      
package2.dll!std::_Construct_in_place<ZipFile,rtl::Reference<comphelper::RefCountedMutex>
 &,com::sun::star::uno::Reference<com::sun::star::io::XInputStream> 
&,com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> 
&,bool,bool,enum ZipFile::Checks>(ZipFile & _Obj, 
rtl::Reference<comphelper::RefCountedMutex> & <_Args_0>, 
com::sun::star::uno::Reference<com::sun::star::io::XInputStream> & <_Args_1>, 
com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & 
<_Args_2>, bool && <_Args_3>, bool && <_Args_4>, ZipFile::Checks && <_Args_5>) 
Line 476++
      
package2.dll!std::_Optional_construct_base<ZipFile>::_Construct<rtl::Reference<comphelper::RefCountedMutex>
 &,com::sun::star::uno::Reference<com::sun::star::io::XInputStream> 
&,com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> 
&,bool,bool,enum ZipFile::Checks>(rtl::Reference<comphelper::RefCountedMutex> & 
<_Args_0>, com::sun::star::uno::Reference<com::sun::star::io::XInputStream> & 
<_Args_1>, 
com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & 
<_Args_2>, bool && <_Args_3>, bool && <_Args_4>, ZipFile::Checks && <_Args_5>) 
Line 157++
      
package2.dll!std::optional<ZipFile>::emplace<rtl::Reference<comphelper::RefCountedMutex>
 &,com::sun::star::uno::Reference<com::sun::star::io::XInputStream> 
&,com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> 
&,bool,bool,enum ZipFile::Checks>(rtl::Reference<comphelper::RefCountedMutex> & 
<_Args_0>, com::sun::star::uno::Reference<com::sun::star::io::XInputStream> & 
<_Args_1>, 
com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & 
<_Args_2>, bool && <_Args_3>, bool && <_Args_4>, ZipFile::Checks && <_Args_5>) 
Line 355++
      package2.dll!OZipFileAccess::initialize(const 
com::sun::star::uno::Sequence<com::sun::star::uno::Any> & aArguments) Line 243++
      
cppuhelper3MSC.dll!cppuhelper::ServiceManager::Data::Implementation::doCreateInstanceWithArguments(const
 com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & 
context, const com::sun::star::uno::Sequence<com::sun::star::uno::Any> & 
arguments) Line 728++
      
cppuhelper3MSC.dll!cppuhelper::ServiceManager::Data::Implementation::createInstanceWithArguments(const
 com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & 
context, bool singletonRequest, const 
com::sun::star::uno::Sequence<com::sun::star::uno::Any> & arguments) Line 690++
      
cppuhelper3MSC.dll!cppuhelper::ServiceManager::createInstanceWithArgumentsAndContext(const
 rtl::OUString & ServiceSpecifier, const 
com::sun::star::uno::Sequence<com::sun::star::uno::Any> & Arguments, const 
com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & 
Context) Line 1014++
      writerperfectlo.dll!writerperfect::WPXSvInputStream::isZip() Line 705++
      writerperfectlo.dll!writerperfect::WPXSvInputStream::isStructured() Line 
489++
      mwaw.dll!MWAWInputStream::isStructured() Line 841++
      mwaw.dll!MWAWInputStream::unsplitInternalMergeStream() Line 574++
      mwaw.dll!MWAWInputStream::MWAWInputStream(librevenge::RVNGInputStream * 
inp, bool inverted, bool checkCompression) Line 79++
      mwaw.dll!MWAWDocument::isFileFormatSupported(librevenge::RVNGInputStream 
* input, MWAWDocument::Type & type, MWAWDocument::Kind & kind) Line 143++
      
wpftwriterlo.dll!MWAWImportFilter::doDetectFormat(librevenge::RVNGInputStream & 
rInput, rtl::OUString & rTypeName) Line 50++
      
wpftwriterlo.dll!writerperfect::detail::ImportFilterImpl<OdtGenerator>::detect(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>
 & Descriptor) Line 136++
      
filterconfiglo.dll!filter::config::TypeDetection::impl_askDetectService(const 
rtl::OUString & sDetectService, utl::MediaDescriptor & rDescriptor) Line 1136++
      
filterconfiglo.dll!filter::config::TypeDetection::impl_detectTypeFlatAndDeep(utl::MediaDescriptor
 & rDescriptor, const 
std::vector<filter::config::FlatDetectionInfo,std::allocator<filter::config::FlatDetectionInfo>>
 & lFlatTypes, bool bAllowDeep, rtl::OUString & rLastChance) Line 1041++
      
filterconfiglo.dll!filter::config::TypeDetection::queryTypeByDescriptor(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>
 & lDescriptor, unsigned char bAllowDeep) Line 436++
      emboleobj.dll!OwnView_Impl::GetFilterNameFromExtentionAndInStream(const 
com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & 
xContext, std::basic_string_view<char16_t,std::char_traits<char16_t>> 
aNameWithExtention, const 
com::sun::star::uno::Reference<com::sun::star::io::XInputStream> & 
xInputStream) Line 207++
      emboleobj.dll!OleEmbeddedObject::TryToConvertToOOo(const 
com::sun::star::uno::Reference<com::sun::star::io::XStream> & xStream) Line 
265++
      emboleobj.dll!OleEmbeddedObject::doVerb(long nVerbID) Line 908++
    
    where ByteGrabber ctor takes an instance of OWriteStream.
    
    Change-Id: Ic60fa1aa3e79848256273c761d132d6bb33c179a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186479
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 587e46e7bc7b2e8520e34b48fa7ef3f188964029)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186544
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/package/source/xstor/owriteablestream.cxx 
b/package/source/xstor/owriteablestream.cxx
index 1de93efe4ddb..1e4799db30cb 100644
--- a/package/source/xstor/owriteablestream.cxx
+++ b/package/source/xstor/owriteablestream.cxx
@@ -1898,6 +1898,25 @@ sal_Int32 SAL_CALL OWriteStream::readSomeBytes( 
uno::Sequence< sal_Int8 >& aData
     return m_xInStream->readSomeBytes( aData, nMaxBytesToRead );
 }
 
+sal_Int32 OWriteStream::readSomeBytes(sal_Int8* pData, sal_Int32 nBytesToRead)
+{
+    osl::MutexGuard aGuard(m_xSharedMutex->GetMutex());
+
+    CheckInitOnDemand();
+
+    if (!m_xInStream.is())
+        throw io::NotConnectedException();
+
+    if (auto pByteReader = 
dynamic_cast<comphelper::ByteReader*>(m_xInStream.get()))
+        return pByteReader->readSomeBytes(pData, nBytesToRead);
+
+    uno::Sequence<sal_Int8> aData;
+    sal_Int32 nRead = m_xInStream->readSomeBytes(aData, nBytesToRead);
+    std::copy_n(aData.getConstArray(), nRead, pData);
+
+    return nRead;
+}
+
 void SAL_CALL OWriteStream::skipBytes( sal_Int32 nBytesToSkip )
 {
     ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
diff --git a/package/source/xstor/owriteablestream.hxx 
b/package/source/xstor/owriteablestream.hxx
index e04b50c99341..7152c30f5e85 100644
--- a/package/source/xstor/owriteablestream.hxx
+++ b/package/source/xstor/owriteablestream.hxx
@@ -232,6 +232,7 @@ class OWriteStream : public css::lang::XTypeProvider
             , public css::embed::XTransactionBroadcaster
             , public css::beans::XPropertySet
             , public ::cppu::OWeakObject
+            , public comphelper::ByteReader
             , public comphelper::ByteWriter
 {
     friend struct OWriteStream_Impl;
@@ -348,9 +349,11 @@ public:
     virtual void SAL_CALL removeTransactionListener(
             const css::uno::Reference< css::embed::XTransactionListener >& 
aListener ) override;
 
+    // comphelper::ByteReader
+    virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) 
override;
+
     // comphelper::ByteWriter
     virtual void writeBytes(const sal_Int8* aData, sal_Int32 nBytesToWrite) 
override;
-
 };
 
 #endif
diff --git a/sw/qa/extras/uiwriter/data/embeddedPPTX.docx 
b/sw/qa/extras/uiwriter/data/embeddedPPTX.docx
new file mode 100644
index 000000000000..58bc03cf9e09
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/embeddedPPTX.docx differ
diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx 
b/sw/qa/extras/uiwriter/uiwriter9.cxx
index 5f92150cfa8a..9d1adeca8b9f 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -1267,6 +1267,14 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf71583)
     }
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf167006)
+{
+    createSwDoc("embeddedPPTX.docx");
+    selectShape(1);
+    // attempt to edit the OLE object. This must not crash.
+    getSwDocShell()->GetWrtShell()->LaunchOLEObj();
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 

Reply via email to