[Libreoffice-commits] core.git: include/oox oox/source sw/qa

Miklos Vajna vmiklos at collabora.co.uk
Fri Jun 2 12:54:30 UTC 2017


 include/oox/core/filterdetect.hxx         |    5 +++--
 oox/source/core/filterdetect.cxx          |   19 ++++++++++++-------
 sw/qa/extras/ooxmlexport/data/bad.docm    |binary
 sw/qa/extras/ooxmlexport/ooxmlexport9.cxx |   11 +++++++++++
 4 files changed, 26 insertions(+), 9 deletions(-)

New commits:
commit 97fa7024ce608b7908aca369e8c643a5de9ebf78
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Jun 2 10:57:23 2017 +0200

    Related: tdf#108269 oox: allow recovering broken DOCM files
    
    The content type inside an OOXML file differs for DOCX and DOCM. These
    must be in sync with the file extension, otherwise MSO refuses to open
    the file. We used to always write the DOCX content-type even for files
    which had the DOCM extension.
    
    Allow users to recover those broken files by detecting a "has docm
    extension but docx content-type" file as docm, so re-saving it will
    produce output that's accepted by MSO as well.
    
    Change-Id: I7d60c6f6c1d0421e95b3dc9e8fff617f101919f5
    Reviewed-on: https://gerrit.libreoffice.org/38342
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/include/oox/core/filterdetect.hxx b/include/oox/core/filterdetect.hxx
index ca717418be99..f5932eab8af6 100644
--- a/include/oox/core/filterdetect.hxx
+++ b/include/oox/core/filterdetect.hxx
@@ -61,7 +61,7 @@ namespace core {
 class FilterDetectDocHandler : public ::cppu::WeakImplHelper< css::xml::sax::XFastDocumentHandler >
 {
 public:
-    explicit            FilterDetectDocHandler( const css::uno::Reference< css::uno::XComponentContext >& rxContext, OUString& rFilter );
+    explicit            FilterDetectDocHandler( const css::uno::Reference< css::uno::XComponentContext >& rxContext, OUString& rFilter, const OUString& rFileName );
     virtual             ~FilterDetectDocHandler() override;
 
     // XFastDocumentHandler
@@ -81,7 +81,7 @@ public:
 private:
     void                parseRelationship( const AttributeList& rAttribs );
 
-    static OUString     getFilterNameFromContentType( const OUString& rContentType );
+    static OUString     getFilterNameFromContentType( const OUString& rContentType, const OUString& rFileName );
     void                parseContentTypesDefault( const AttributeList& rAttribs );
     void                parseContentTypesOverride( const AttributeList& rAttribs );
 
@@ -89,6 +89,7 @@ private:
     typedef ::std::vector< sal_Int32 > ContextVector;
 
     OUString&           mrFilterName;
+    OUString            maFileName;
     ContextVector       maContextStack;
     OUString            maTargetPath;
     css::uno::Reference< css::uno::XComponentContext > mxContext;
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
index 1882572f12d5..226668dfc767 100644
--- a/oox/source/core/filterdetect.cxx
+++ b/oox/source/core/filterdetect.cxx
@@ -52,8 +52,9 @@ using utl::MediaDescriptor;
 using comphelper::IDocPasswordVerifier;
 using comphelper::DocPasswordVerifierResult;
 
-FilterDetectDocHandler::FilterDetectDocHandler( const  Reference< XComponentContext >& rxContext, OUString& rFilterName ) :
+FilterDetectDocHandler::FilterDetectDocHandler( const  Reference< XComponentContext >& rxContext, OUString& rFilterName, const OUString& rFileName ) :
     mrFilterName( rFilterName ),
+    maFileName(rFileName),
     mxContext( rxContext )
 {
     maContextStack.reserve( 2 );
@@ -160,12 +161,12 @@ void FilterDetectDocHandler::parseRelationship( const AttributeList& rAttribs )
     }
 }
 
-OUString FilterDetectDocHandler::getFilterNameFromContentType( const OUString& rContentType )
+OUString FilterDetectDocHandler::getFilterNameFromContentType( const OUString& rContentType, const OUString& rFileName )
 {
-    if( rContentType == "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" )
+    if( rContentType == "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" && !rFileName.endsWith("docm") )
         return OUString( "writer_MS_Word_2007" );
 
-    if( rContentType == "application/vnd.ms-word.document.macroEnabled.main+xml" )
+    if( rContentType == "application/vnd.ms-word.document.macroEnabled.main+xml" || rFileName.endsWith("docm") )
         return OUString( "writer_MS_Word_2007_VBA" );
 
     if( rContentType == "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml" ||
@@ -209,14 +210,14 @@ void FilterDetectDocHandler::parseContentTypesDefault( const AttributeList& rAtt
         OUString aExtension = rAttribs.getString( XML_Extension, OUString() );
         sal_Int32 nExtPos = maTargetPath.getLength() - aExtension.getLength();
         if( (nExtPos > 0) && (maTargetPath[ nExtPos - 1 ] == '.') && maTargetPath.match( aExtension, nExtPos ) )
-            mrFilterName = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) );
+            mrFilterName = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ), maFileName );
     }
 }
 
 void FilterDetectDocHandler::parseContentTypesOverride( const AttributeList& rAttribs )
 {
     if( rAttribs.getString( XML_PartName, OUString() ).equals( maTargetPath ) )
-        mrFilterName = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) );
+        mrFilterName = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ), maFileName );
 }
 
 /* Helper for XServiceInfo */
@@ -400,7 +401,11 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq
             aParser.registerNamespace( NMSP_packageRel );
             aParser.registerNamespace( NMSP_officeRel );
             aParser.registerNamespace( NMSP_packageContentTypes );
-            aParser.setDocumentHandler( new FilterDetectDocHandler( mxContext, aFilterName ) );
+
+            OUString aFileName;
+            aMediaDescriptor[utl::MediaDescriptor::PROP_URL()] >>= aFileName;
+
+            aParser.setDocumentHandler( new FilterDetectDocHandler( mxContext, aFilterName, aFileName ) );
 
             /*  Parse '_rels/.rels' to get the target path and '[Content_Types].xml'
                 to determine the content type of the part at the target path. */
diff --git a/sw/qa/extras/ooxmlexport/data/bad.docm b/sw/qa/extras/ooxmlexport/data/bad.docm
new file mode 100644
index 000000000000..b1e83220aa83
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/bad.docm differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index 9d1a5e161fcc..0191b8a38023 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -24,6 +24,9 @@
 #include <com/sun/star/text/HoriOrientation.hpp>
 #include <com/sun/star/text/RelOrientation.hpp>
 
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+
 class Test : public SwModelTestBase
 {
 public:
@@ -82,6 +85,14 @@ DECLARE_SW_ROUNDTRIP_TEST(testDocmSave, "hello.docm", nullptr, DocmTest)
                     "application/vnd.ms-word.document.macroEnabled.main+xml");
 }
 
+DECLARE_SW_ROUNDTRIP_TEST(testBadDocm, "bad.docm", nullptr, DocmTest)
+{
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+    // This was 'MS Word 2007 XML', broken docm files were not recognized.
+    CPPUNIT_ASSERT_EQUAL(OUString("MS Word 2007 XML VBA"), pTextDoc->GetDocShell()->GetMedium()->GetFilter()->GetName());
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf92045, "tdf92045.docx")
 {
     // This was true, <w:effect w:val="none"/> resulted in setting the blinking font effect.


More information about the Libreoffice-commits mailing list