diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2017-04-04 22:37:45 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2017-04-06 20:52:24 +0000 |
commit | f4a693ef5f2f07dc2817f9a28183cf7c5a7bb7e6 (patch) | |
tree | d4ca37c6a108a60e450f72fee2bf3cf49fd7d268 /filter/source | |
parent | 5e0892877ff84bb70464e745be9e88b2c351a57f (diff) |
tdf#106955: Detect XML by MediaType
According to Extensible Markup Language (XML) 1.0 (see
https://www.w3.org/TR/2008/REC-xml-20081126/#sec-prolog-dtd),
all parts of XML prolog (including XML declaration) are optional,
so XML stream without <?xml ... ?> is well-formed (though not
valid).
XMLFilterDetect uses only XML declaration to detect if the file is
to be processed further. However, this creates problems with said
documents.
This commit checks if the document has MediaType set to one of
known XML media types, in case when the check for XML declaration
failed.
Change-Id: I31627c0e3a39bee241f609650280ebac3f1cede8
Reviewed-on: https://gerrit.libreoffice.org/36101
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
(cherry picked from commit 156f778593ca9c57845076a88c6b544a63e12e7a)
Reviewed-on: https://gerrit.libreoffice.org/36133
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'filter/source')
-rw-r--r-- | filter/source/xmlfilterdetect/filterdetect.cxx | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/filter/source/xmlfilterdetect/filterdetect.cxx b/filter/source/xmlfilterdetect/filterdetect.cxx index 8ce2522dfb2c..3e13cb17d607 100644 --- a/filter/source/xmlfilterdetect/filterdetect.cxx +++ b/filter/source/xmlfilterdetect/filterdetect.cxx @@ -27,6 +27,7 @@ #include <cppuhelper/supportsservice.hxx> #include <ucbhelper/content.hxx> #include <unotools/ucbstreamhelper.hxx> +#include <svl/inettype.hxx> #include <memory> using namespace com::sun::star::container; @@ -49,6 +50,25 @@ OUString supportedByType( const OUString& clipBoardFormat, const OUString& resu return sTypeName; } +bool IsMediaTypeXML( const OUString& mediaType ) +{ + if (!mediaType.isEmpty()) + { + OUString sType, sSubType; + INetContentTypes::parse(mediaType, sType, sSubType); + if (sType.equalsIgnoreAsciiCase("application")) + { + // RFC 3023: application/xml; don't detect text/xml + if (sSubType.equalsIgnoreAsciiCase("xml")) + return true; + // Registered media types: application/XXXX+xml + if (sSubType.endsWithIgnoreAsciiCase("+xml")) + return true; + } + } + return false; +} + } OUString SAL_CALL FilterDetect::detect( css::uno::Sequence< css::beans::PropertyValue >& aArguments ) throw( css::uno::RuntimeException, std::exception ) @@ -125,9 +145,30 @@ OUString SAL_CALL FilterDetect::detect( css::uno::Sequence< css::beans::Property resultString = read_uInt16s_ToOUString( *pInStream, nSize ); if ( !resultString.startsWith( "<?xml" ) ) - // This is not an XML stream. It makes no sense to try to detect - // a non-XML file type here. - return OUString(); + { + // Check the content type; XML declaration is optional in XML files according to XML 1.0 ch.2.8 + // (see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-prolog-dtd) + OUString sMediaType; + try + { + ::ucbhelper::Content aContent( + sUrl, Reference< css::ucb::XCommandEnvironment >(), + mxCtx); + aContent.getPropertyValue("MediaType") >>= sMediaType; + if (sMediaType.isEmpty()) + { + aContent.getPropertyValue("Content-Type") >>= sMediaType; + } + } + catch (...) {} + + if (!IsMediaTypeXML(sMediaType)) + { + // This is not an XML stream. It makes no sense to try to detect + // a non-XML file type here. + return OUString(); + } + } // test typedetect code Reference <XNameAccess> xTypeCont(mxCtx->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", mxCtx), UNO_QUERY); |