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

Reply via email to