summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filter/CppunitTest_filter_textfilterdetect.mk7
-rw-r--r--filter/Library_textfd.mk1
-rw-r--r--filter/qa/unit/data/empty.pptx0
-rw-r--r--filter/qa/unit/textfilterdetect.cxx68
-rw-r--r--filter/source/textfilterdetect/filterdetect.cxx32
-rw-r--r--include/tools/stream.hxx6
-rw-r--r--sfx2/source/doc/objstor.cxx6
-rw-r--r--tools/source/stream/stream.cxx20
8 files changed, 111 insertions, 29 deletions
diff --git a/filter/CppunitTest_filter_textfilterdetect.mk b/filter/CppunitTest_filter_textfilterdetect.mk
index dfcaee9ce16a..49cd09fd79b4 100644
--- a/filter/CppunitTest_filter_textfilterdetect.mk
+++ b/filter/CppunitTest_filter_textfilterdetect.mk
@@ -34,12 +34,7 @@ $(eval $(call gb_CppunitTest_use_ure,filter_textfilterdetect))
$(eval $(call gb_CppunitTest_use_vcl,filter_textfilterdetect))
-$(eval $(call gb_CppunitTest_use_components,filter_textfilterdetect,\
- configmgr/source/configmgr \
- filter/source/textfilterdetect/textfd \
- ucb/source/core/ucb1 \
- ucb/source/ucp/file/ucpfile1 \
-))
+$(eval $(call gb_CppunitTest_use_rdb,filter_textfilterdetect,services))
$(eval $(call gb_CppunitTest_use_configuration,filter_textfilterdetect))
diff --git a/filter/Library_textfd.mk b/filter/Library_textfd.mk
index e6d3889410af..c6155f1e9876 100644
--- a/filter/Library_textfd.mk
+++ b/filter/Library_textfd.mk
@@ -23,6 +23,7 @@ $(eval $(call gb_Library_use_libraries,textfd,\
cppuhelper \
cppu \
sal \
+ sfx \
tl \
utl \
svt \
diff --git a/filter/qa/unit/data/empty.pptx b/filter/qa/unit/data/empty.pptx
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/filter/qa/unit/data/empty.pptx
diff --git a/filter/qa/unit/textfilterdetect.cxx b/filter/qa/unit/textfilterdetect.cxx
index 3711c416c2c5..cc86fe04c3d5 100644
--- a/filter/qa/unit/textfilterdetect.cxx
+++ b/filter/qa/unit/textfilterdetect.cxx
@@ -7,49 +7,60 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
#include <comphelper/processfactory.hxx>
#include <comphelper/propertyvalue.hxx>
-#include <test/bootstrapfixture.hxx>
#include <unotools/mediadescriptor.hxx>
#include <unotools/streamwrap.hxx>
+#include <tools/stream.hxx>
-namespace com
-{
-namespace sun
-{
-namespace star
-{
-namespace io
+namespace com::sun::star::io
{
class XInputStream;
}
-}
-}
-}
using namespace com::sun::star;
namespace
{
/// Test class for PlainTextFilterDetect.
-class TextFilterDetectTest : public test::BootstrapFixture
+class TextFilterDetectTest : public test::BootstrapFixture, public unotest::MacrosTest
{
-public:
- void testTdf114428();
+ uno::Reference<uno::XComponentContext> mxComponentContext;
+ uno::Reference<lang::XComponent> mxComponent;
- CPPUNIT_TEST_SUITE(TextFilterDetectTest);
- CPPUNIT_TEST(testTdf114428);
- CPPUNIT_TEST_SUITE_END();
+public:
+ void setUp() override;
+ void tearDown() override;
+ uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
};
+void TextFilterDetectTest::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxComponentContext.set(comphelper::getComponentContext(getMultiServiceFactory()));
+ mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void TextFilterDetectTest::tearDown()
+{
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ test::BootstrapFixture::tearDown();
+}
+
char const DATA_DIRECTORY[] = "/filter/qa/unit/data/";
-void TextFilterDetectTest::testTdf114428()
+CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testTdf114428)
{
- uno::Reference<uno::XComponentContext> xComponentContext
- = comphelper::getComponentContext(getMultiServiceFactory());
uno::Reference<document::XExtendedFilterDetection> xDetect(
getMultiServiceFactory()->createInstance("com.sun.star.comp.filters.PlainTextFilterDetect"),
uno::UNO_QUERY);
@@ -68,7 +79,22 @@ void TextFilterDetectTest::testTdf114428()
CPPUNIT_ASSERT_EQUAL(OUString("HTML (StarWriter)"), aFilterName);
}
-CPPUNIT_TEST_SUITE_REGISTRATION(TextFilterDetectTest);
+CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testEmptyFile)
+{
+ // Given an empty file, with a pptx extension
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.pptx";
+
+ // When loading the file
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure it is opened in Impress.
+ uno::Reference<lang::XServiceInfo> xServiceInfo(getComponent(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xServiceInfo.is());
+
+ // Without the accompanying fix in place, this test would have failed, as it was opened in
+ // Writer instead.
+ CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.presentation.PresentationDocument"));
+}
}
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/filter/source/textfilterdetect/filterdetect.cxx b/filter/source/textfilterdetect/filterdetect.cxx
index cb0055c34565..c18751c0e66c 100644
--- a/filter/source/textfilterdetect/filterdetect.cxx
+++ b/filter/source/textfilterdetect/filterdetect.cxx
@@ -21,6 +21,8 @@
#include <com/sun/star/io/XInputStream.hpp>
#include <cppuhelper/supportsservice.hxx>
#include <memory>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/docfilt.hxx>
#define WRITER_TEXT_FILTER "Text"
#define CALC_TEXT_FILTER "Text - txt - csv (StarCalc)"
@@ -129,6 +131,34 @@ bool IsHTMLStream( const uno::Reference<io::XInputStream>& xInStream )
return GetHTMLToken( OStringToOUString( aToken.toAsciiLowerCase(), RTL_TEXTENCODING_ASCII_US ) ) != HtmlTokenId::NONE;
}
+/**
+ * Given an (empty) file URL in rMediaDesc and rExt, looks up the best filter type for it and
+ * writes the type name to rType, the filter name to rMediaDesc.
+ */
+bool HandleEmptyFileUrlByExtension(MediaDescriptor& rMediaDesc, const OUString& rExt,
+ OUString& rType)
+{
+ OUString aURL = rMediaDesc.getUnpackedValueOrDefault(MediaDescriptor::PROP_URL(), OUString());
+ if (!tools::isEmptyFileUrl(aURL))
+ {
+ return false;
+ }
+
+ if (rExt.isEmpty())
+ {
+ return false;
+ }
+
+ std::shared_ptr<const SfxFilter> pFilter(SfxFilterMatcher().GetFilter4Extension(rExt));
+ if (!pFilter)
+ {
+ return false;
+ }
+
+ rMediaDesc[MediaDescriptor::PROP_FILTERNAME()] <<= pFilter->GetFilterName();
+ rType = pFilter->GetTypeName();
+ return true;
+}
}
PlainTextFilterDetect::PlainTextFilterDetect() {}
@@ -194,7 +224,7 @@ OUString SAL_CALL PlainTextFilterDetect::detect(uno::Sequence<beans::PropertyVal
aMediaDesc[MediaDescriptor::PROP_FILTERNAME()] <<= OUString(WRITER_TEXT_FILTER);
else if (aExt == "csv" || aExt == "tsv" || aExt == "tab" || aExt == "xls" || aName.endsWith(".csv.gz"))
aMediaDesc[MediaDescriptor::PROP_FILTERNAME()] <<= OUString(CALC_TEXT_FILTER);
- else
+ else if (!HandleEmptyFileUrlByExtension(aMediaDesc, aExt, aType))
aMediaDesc[MediaDescriptor::PROP_FILTERNAME()] <<= OUString(WRITER_TEXT_FILTER);
}
diff --git a/include/tools/stream.hxx b/include/tools/stream.hxx
index 370372aba454..c258425cdd0c 100644
--- a/include/tools/stream.hxx
+++ b/include/tools/stream.hxx
@@ -568,6 +568,12 @@ inline std::size_t write_uInt16_lenPrefixed_uInt8s_FromOUString(SvStream& rStrm,
SAL_WARN_UNUSED_RESULT TOOLS_DLLPUBLIC bool checkSeek(SvStream &rSt, sal_uInt64 nOffset);
+namespace tools
+{
+/// Is rUrl a file:// URL with no contents?
+TOOLS_DLLPUBLIC bool isEmptyFileUrl(const OUString& rUrl);
+}
+
// FileStream
class TOOLS_DLLPUBLIC SvFileStream : public SvStream
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx
index 66ec9a8d16f6..50ec51f7e546 100644
--- a/sfx2/source/doc/objstor.cxx
+++ b/sfx2/source/doc/objstor.cxx
@@ -2220,7 +2220,11 @@ bool SfxObjectShell::ImportFrom(SfxMedium& rMedium,
// #i119492# During loading, some OLE objects like chart will be set
// modified flag, so needs to reset the flag to false after loading
- bool bRtn = xLoader->filter( aArgs );
+ bool bRtn = true;
+ if (!tools::isEmptyFileUrl(rMedium.GetName()))
+ {
+ bRtn = xLoader->filter(aArgs);
+ }
uno::Sequence < OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
for ( sal_Int32 n = 0; n < aNames.getLength(); ++n )
{
diff --git a/tools/source/stream/stream.cxx b/tools/source/stream/stream.cxx
index ea9f533b3af3..49ebb1ba7512 100644
--- a/tools/source/stream/stream.cxx
+++ b/tools/source/stream/stream.cxx
@@ -33,6 +33,7 @@
#include <sal/log.hxx>
#include <comphelper/fileformat.h>
+#include <comphelper/fileurl.hxx>
static void swapNibbles(unsigned char &c)
{
@@ -1408,6 +1409,25 @@ bool checkSeek(SvStream &rSt, sal_uInt64 nOffset)
return (nOffset <= nMaxSeek && rSt.Seek(nOffset) == nOffset);
}
+namespace tools
+{
+bool isEmptyFileUrl(const OUString& rUrl)
+{
+ if (!comphelper::isFileUrl(rUrl))
+ {
+ return false;
+ }
+
+ SvFileStream aStream(rUrl, StreamMode::READ);
+ if (!aStream.IsOpen())
+ {
+ return false;
+ }
+
+ return aStream.remainingSize() == 0;
+}
+}
+
//STREAM_SEEK_TO_END in some of the Seek backends is special cased to be
//efficient, in others e.g. SotStorageStream it's really horribly slow, and in
//those this should be overridden