diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-10-28 14:54:52 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2020-10-31 22:52:59 +0100 |
commit | 44ee2734c1ae6d58e8aee0ff79cfebdf8aef4457 (patch) | |
tree | 391f9a628c785c139c9a19c89023b928a9bd5135 /filter | |
parent | c7952cb2646f7c385b68f8e7acce5cf2713c567c (diff) |
tdf#123476 filter: try to detect 0-byte files based on extension
A 0-byte ("empty") pptx file is obviously junk input, so it's not
surprising if the catch-all generic_Text filter is chosen to open it in
Writer at the end.
But we can do better: if we really get an empty file URL with an
extension we can recognize, that we can fake the filter type / filter
name, so the empty "presentation" opens in Impress, and also a re-save
works as expected.
This builds on top of commit 8a201be240b6d408d15166be7ffc576b9e123634
(fdo#68903 Import .tsv and .xls plain text files in Calc by default,
2013-10-27), just the new way works for all supported file extensions
and also with filters which would not handle empty input (e.g. pptx
refuses the import if the ZIP storage is broken).
Change-Id: Ie01650a5eb6ca42c35e090133965467b621bb526
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104939
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105039
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Diffstat (limited to 'filter')
-rw-r--r-- | filter/CppunitTest_filter_textfilterdetect.mk | 7 | ||||
-rw-r--r-- | filter/Library_textfd.mk | 1 | ||||
-rw-r--r-- | filter/qa/unit/data/empty.pptx | 0 | ||||
-rw-r--r-- | filter/qa/unit/textfilterdetect.cxx | 68 | ||||
-rw-r--r-- | filter/source/textfilterdetect/filterdetect.cxx | 32 |
5 files changed, 80 insertions, 28 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); } |