diff --git a/oox/inc/oox/core/filterdetect.hxx b/oox/inc/oox/core/filterdetect.hxx index b83b13910349..39b8abe8efb9 100644 --- a/oox/inc/oox/core/filterdetect.hxx +++ b/oox/inc/oox/core/filterdetect.hxx @@ -59,7 +59,7 @@ namespace core { class FilterDetectDocHandler : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastDocumentHandler > { public: - explicit FilterDetectDocHandler( ::rtl::OUString& rFilter ); + explicit FilterDetectDocHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext, ::rtl::OUString& rFilter ); virtual ~FilterDetectDocHandler(); // XFastDocumentHandler @@ -91,6 +91,7 @@ private: ::rtl::OUString& mrFilterName; ContextVector maContextStack; ::rtl::OUString maTargetPath; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxContext; }; // ============================================================================ diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index dd218a616c0e..75e54f9eb123 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -39,6 +39,7 @@ #include "oox/helper/binaryoutputstream.hxx" #include "oox/helper/zipstorage.hxx" #include "oox/ole/olestorage.hxx" +#include namespace oox { namespace core { @@ -57,8 +58,8 @@ using ::rtl::OUString; // ============================================================================ -FilterDetectDocHandler::FilterDetectDocHandler( OUString& rFilterName ) : - mrFilterName( rFilterName ) +FilterDetectDocHandler::FilterDetectDocHandler( const Reference< XComponentContext >& rxContext, OUString& rFilterName ) : + mrFilterName( rFilterName ), mxContext( rxContext ) { maContextStack.reserve( 2 ); } @@ -163,7 +164,24 @@ void FilterDetectDocHandler::parseRelationship( const AttributeList& rAttribs ) { OUString aType = rAttribs.getString( XML_Type, OUString() ); if( aType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ) ) ) - maTargetPath = OUString( sal_Unicode( '/' ) ) + rAttribs.getString( XML_Target, OUString() ); + { + Reference< com::sun::star::uri::XUriReferenceFactory > xFac = com::sun::star::uri::UriReferenceFactory::create( mxContext ); + try + { + // use '/' to representent the root of the zip package ( and provide a 'file' scheme to + // keep the XUriReference implementation happy ) + Reference< com::sun::star::uri::XUriReference > xBase = xFac->parse( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("file:///" ) ) ); + + Reference< com::sun::star::uri::XUriReference > xPart = xFac->parse( rAttribs.getString( XML_Target, OUString() ) ); + Reference< com::sun::star::uri::XUriReference > xAbs = xFac->makeAbsolute( xBase, xPart, sal_True, com::sun::star::uri::RelativeUriExcessParentSegments::RelativeUriExcessParentSegments_RETAIN ); + + if ( xAbs.is() ) + maTargetPath = xAbs->getPath(); + } + catch( Exception& e) + { + } + } } OUString FilterDetectDocHandler::getFilterNameFromContentType( const OUString& rContentType ) const @@ -659,7 +677,7 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq aParser.registerNamespace( NMSP_packageRel ); aParser.registerNamespace( NMSP_officeRel ); aParser.registerNamespace( NMSP_packageContentTypes ); - aParser.setDocumentHandler( new FilterDetectDocHandler( aFilterName ) ); + aParser.setDocumentHandler( new FilterDetectDocHandler( mxContext, aFilterName ) ); /* Parse '_rels/.rels' to get the target path and '[Content_Types].xml' to determine the content type of the part at the target path. */ @@ -667,7 +685,7 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq aParser.parseStream( aZipStorage, CREATE_OUSTRING( "[Content_Types].xml" ) ); } } - catch( Exception& ) + catch( Exception& e ) { } diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx index 2cb058ea65d4..d5f01b86ff9e 100644 --- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx @@ -32,6 +32,7 @@ #include #include +#include //#define DEBUG_STREAM @@ -100,6 +101,11 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference ::rtl::OUString & rDocumentTarget) { bool bFound = false; + static uno::Reference< com::sun::star::uri::XUriReferenceFactory > xFac = ::com::sun::star::uri::UriReferenceFactory::create( mxContext ); + // use '/' to representent the root of the zip package ( and provide a 'file' scheme to + // keep the XUriReference implementation happy ) + // add mspath to represent the 'source' of this stream + uno::Reference< com::sun::star::uri::XUriReference > xBase = xFac->parse( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("file:///" ) ) + msPath ); static rtl::OUString sType(RTL_CONSTASCII_USTRINGPARAM("Type")); static rtl::OUString sId(RTL_CONSTASCII_USTRINGPARAM("Id")); @@ -190,8 +196,16 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference rDocumentTarget = sMyTarget; else { - rDocumentTarget = msPath; - rDocumentTarget += sMyTarget; + // 'Target' is a relative Uri, so a 'Target=/path' + // with a base Uri of file://base/foo will resolve to + // file://base/word. We need something more than some + // simple string concatination here to handle that. + uno::Reference< com::sun::star::uri::XUriReference > xPart = xFac->parse( sMyTarget ); + uno::Reference< com::sun::star::uri::XUriReference > xAbs = xFac->makeAbsolute( xBase, xPart, sal_True, com::sun::star::uri::RelativeUriExcessParentSegments::RelativeUriExcessParentSegments_RETAIN ); + rDocumentTarget = xAbs->getPath(); + // path will start with the fragment separator. need to + // remove that + rDocumentTarget = rDocumentTarget.copy( 1 ); } break;