filter/qa/unit/data/test_pseudo_pwi.xml | 1 filter/qa/unit/textfilterdetect.cxx | 14 +++++ filter/source/xmlfilterdetect/filterdetect.cxx | 68 +++++++++++-------------- 3 files changed, 45 insertions(+), 38 deletions(-)
New commits: commit 9fcc9fe94f5073632c4fc50b153767acfa8f87ff Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Mon Oct 7 17:23:03 2024 +0500 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Fri Oct 11 18:50:06 2024 +0200 tdf#163295: XMLFilterDetect: make sure to only detect own types Since commit 872dba61a1a45dceb4ffb662f6da61fb67d750e5 (INTEGRATION: CWS xmlfilter01 (1.1.2.3.2.1.16); FILE MERGED, 2003-04-04), XMLFilterDetect service uses Clipboardformat field in filterdetect. Thus, it detects any file starting with "<?xml" and having string "pwi" as "writer_PocketWord_File", because writer_PocketWord_File.xcu has the text "doctype:pwi" as the value of its ClipboardFormat. The problem is: since commit 1e6e891016ae926868de493ab0e29871a2d06b95 (restore PocketWord filter, this time backed by libwps, 2020-09-27), this format is not handled by XMLFilterDetect service. So the filter mis-detects some else filter's data, which then isn't accepted there. This change makes the code of FilterDetect::detect to make sure that it only processes its own data, checking DetectService property, too. I didn't remove the ClipboardFormat property value from the mentioned XCU, because (1) I don't know if it may be used by other code; and (2) because it allows to have the sensible unit test. Change-Id: I02fafe8df10f64640305d45cf1461b0a37552630 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174607 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins (cherry picked from commit 8f25697591ecfd615a3142528ca13ee4d0d2c562) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174662 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/filter/qa/unit/data/test_pseudo_pwi.xml b/filter/qa/unit/data/test_pseudo_pwi.xml new file mode 100644 index 000000000000..98cdd7e0bd60 --- /dev/null +++ b/filter/qa/unit/data/test_pseudo_pwi.xml @@ -0,0 +1 @@ +<?xmlpwi \ No newline at end of file diff --git a/filter/qa/unit/textfilterdetect.cxx b/filter/qa/unit/textfilterdetect.cxx index ecd982d0f194..2a5af96f47de 100644 --- a/filter/qa/unit/textfilterdetect.cxx +++ b/filter/qa/unit/textfilterdetect.cxx @@ -11,6 +11,7 @@ #include <com/sun/star/document/XExtendedFilterDetection.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/document/XTypeDetection.hpp> #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> #include <com/sun/star/sheet/XCellRangesAccess.hpp> #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> @@ -236,6 +237,19 @@ CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testHybridPDFFile) } } #endif // _WIN32 + +CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testTdf163295) +{ + // Given a file with a content of "<?xmlpwi" - yes, it's not an XML, and not a pwi file + auto xDetection(comphelper::getProcessServiceFactory() + ->createInstance(u"com.sun.star.document.TypeDetection"_ustr) + .queryThrow<document::XTypeDetection>()); + OUString url = createFileURL(u"test_pseudo_pwi.xml"); + css::uno::Sequence mediaDescriptor{ comphelper::makePropertyValue(u"URL"_ustr, url) }; + OUString detection = xDetection->queryTypeByDescriptor(mediaDescriptor, true); + // Without the fix, this was "writer_PocketWord_File" + CPPUNIT_ASSERT_EQUAL(u"generic_Text"_ustr, detection); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/filter/source/xmlfilterdetect/filterdetect.cxx b/filter/source/xmlfilterdetect/filterdetect.cxx index 9fb1f7b66a03..3c23f6e9097f 100644 --- a/filter/source/xmlfilterdetect/filterdetect.cxx +++ b/filter/source/xmlfilterdetect/filterdetect.cxx @@ -73,30 +73,24 @@ bool IsMediaTypeXML( const OUString& mediaType ) OUString SAL_CALL FilterDetect::detect( css::uno::Sequence< css::beans::PropertyValue >& aArguments ) { - OUString sTypeName; OUString sUrl; - Sequence<PropertyValue > lProps ; - css::uno::Reference< css::io::XInputStream > xInStream; - const PropertyValue * pValue = aArguments.getConstArray(); - sal_Int32 nLength; - OUString resultString; - nLength = aArguments.getLength(); + sal_Int32 nLength = aArguments.getLength(); sal_Int32 location=nLength; for (sal_Int32 i = 0 ; i < nLength; i++) { - if ( pValue[i].Name == "TypeName" ) + if (aArguments[i].Name == "TypeName") { location=i; } - else if ( pValue[i].Name == "URL" ) + else if (aArguments[i].Name == "URL") { - pValue[i].Value >>= sUrl; + aArguments[i].Value >>= sUrl; } - else if ( pValue[i].Name == "InputStream" ) + else if (aArguments[i].Name == "InputStream") { - pValue[i].Value >>= xInStream ; + aArguments[i].Value >>= xInStream; } } try @@ -109,7 +103,7 @@ OUString SAL_CALL FilterDetect::detect( css::uno::Sequence< css::beans::Property xInStream = aContent.openStream(); if (!xInStream.is()) { - return sTypeName; + return {}; } } @@ -134,6 +128,7 @@ OUString SAL_CALL FilterDetect::detect( css::uno::Sequence< css::beans::Property pInStream->Seek( STREAM_SEEK_TO_BEGIN ); } + OUString resultString; if ( nUniPos == 3 || ( nUniPos == 0 && !bTryUtf16 ) ) // UTF-8 or non-Unicode { OString const str(read_uInt8s_ToOString(*pInStream, nSize)); @@ -175,25 +170,32 @@ OUString SAL_CALL FilterDetect::detect( css::uno::Sequence< css::beans::Property Sequence < OUString > myTypes= xTypeCont->getElementNames(); nLength = myTypes.getLength(); - sal_Int32 new_nlength=0; - sal_Int32 i = 0 ; - while ((i < nLength) && (sTypeName.isEmpty())) + for (const OUString& myType : myTypes) { - Any elem = xTypeCont->getByName(myTypes[i]); - elem >>=lProps; - new_nlength = lProps.getLength(); - sal_Int32 j =0; - while (j < new_nlength && (sTypeName.isEmpty())) + Sequence<PropertyValue> lProps; + xTypeCont->getByName(myType) >>= lProps; + OUString detectService, clipboardFormat; + for (const PropertyValue& prop : lProps) { - OUString tmpStr; - lProps[j].Value >>=tmpStr; - if ( lProps[j].Name == "ClipboardFormat" && !tmpStr.isEmpty() ) + if (prop.Name == "DetectService") + prop.Value >>= detectService; + else if (prop.Name == "ClipboardFormat") + prop.Value >>= clipboardFormat; + } + if (!clipboardFormat.isEmpty() && detectService == getImplementationName()) + { + OUString sTypeName = supportedByType(clipboardFormat, resultString, myType); + if (!sTypeName.isEmpty()) { - sTypeName = supportedByType(tmpStr,resultString, myTypes[i]); + if (location == aArguments.getLength()) + { + aArguments.realloc(aArguments.getLength() + 1); + aArguments.getArray()[location].Name = "TypeName"; + } + aArguments.getArray()[location].Value <<= sTypeName; + return sTypeName; } - j++; } - i++; } } catch (const Exception &) @@ -201,17 +203,7 @@ OUString SAL_CALL FilterDetect::detect( css::uno::Sequence< css::beans::Property TOOLS_WARN_EXCEPTION("filter.xmlfd", "An Exception occurred while opening File stream"); } - if (!sTypeName.isEmpty()) - { - if (location == aArguments.getLength()) - { - aArguments.realloc(nLength+1); - aArguments.getArray()[location].Name = "TypeName"; - } - aArguments.getArray()[location].Value <<=sTypeName; - } - - return sTypeName; + return {}; } // XInitialization