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 32f45f1bca454659d17dea80499b635a43ae4490 Author: Miklos Vajna <[email protected]> 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. (cherry picked from commit 97fa7024ce608b7908aca369e8c643a5de9ebf78) Change-Id: I7d60c6f6c1d0421e95b3dc9e8fff617f101919f5 Reviewed-on: https://gerrit.libreoffice.org/38356 Tested-by: Jenkins <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> 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 6a629f12580a..f96280aa893f 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx @@ -23,6 +23,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: @@ -81,6 +84,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. _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
