LCOV - code coverage report
Current view: top level - libreoffice/package/source/zippackage - ZipPackage.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 588 894 65.8 %
Date: 2012-12-27 Functions: 23 53 43.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : // MARKER( update_precomp.py ): autogen include statement, do not remove
      21             : #include <ZipPackage.hxx>
      22             : #include <ZipPackageSink.hxx>
      23             : #include <ZipEnumeration.hxx>
      24             : #include <ZipPackageStream.hxx>
      25             : #include <ZipPackageFolder.hxx>
      26             : #include <ZipOutputStream.hxx>
      27             : #include <ZipPackageBuffer.hxx>
      28             : #include <ZipFile.hxx>
      29             : #include <PackageConstants.hxx>
      30             : #include <com/sun/star/beans/PropertyValue.hpp>
      31             : #include <com/sun/star/packages/zip/ZipConstants.hpp>
      32             : #include <com/sun/star/packages/manifest/ManifestReader.hpp>
      33             : #include <com/sun/star/packages/manifest/ManifestWriter.hpp>
      34             : #include <com/sun/star/io/TempFile.hpp>
      35             : #include <com/sun/star/io/XStream.hpp>
      36             : #include <com/sun/star/io/XInputStream.hpp>
      37             : #include <com/sun/star/io/XOutputStream.hpp>
      38             : #include <com/sun/star/io/XTruncate.hpp>
      39             : #include <com/sun/star/io/XSeekable.hpp>
      40             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      41             : #include <com/sun/star/container/XNameContainer.hpp>
      42             : #include <com/sun/star/ucb/IOErrorCode.hpp>
      43             : #include <ucbhelper/content.hxx>
      44             : #include <cppuhelper/factory.hxx>
      45             : #include <cppuhelper/exc_hlp.hxx>
      46             : #include <com/sun/star/ucb/TransferInfo.hpp>
      47             : #include <com/sun/star/ucb/NameClash.hpp>
      48             : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
      49             : #include <com/sun/star/ucb/OpenMode.hpp>
      50             : #include <com/sun/star/ucb/XProgressHandler.hpp>
      51             : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
      52             : #include <com/sun/star/ucb/UniversalContentBroker.hpp>
      53             : #include <com/sun/star/io/XActiveDataStreamer.hpp>
      54             : #include <com/sun/star/embed/XTransactedObject.hpp>
      55             : #include <com/sun/star/embed/UseBackupException.hpp>
      56             : #include <com/sun/star/embed/StorageFormats.hpp>
      57             : #include <com/sun/star/beans/NamedValue.hpp>
      58             : #include <com/sun/star/xml/crypto/DigestID.hpp>
      59             : #include <com/sun/star/xml/crypto/CipherID.hpp>
      60             : #include <cppuhelper/implbase1.hxx>
      61             : #include <ContentInfo.hxx>
      62             : #include <cppuhelper/typeprovider.hxx>
      63             : #include <rtl/uri.hxx>
      64             : #include <rtl/random.h>
      65             : #include <rtl/logfile.hxx>
      66             : #include <rtl/instance.hxx>
      67             : #include <osl/time.h>
      68             : #include "com/sun/star/io/XAsyncOutputMonitor.hpp"
      69             : 
      70             : #include <cstring>
      71             : #include <memory>
      72             : #include <vector>
      73             : 
      74             : #include <ucbhelper/fileidentifierconverter.hxx>
      75             : #include <comphelper/processfactory.hxx>
      76             : #include <comphelper/seekableinput.hxx>
      77             : #include <comphelper/storagehelper.hxx>
      78             : #include <comphelper/ofopxmlhelper.hxx>
      79             : #include <comphelper/documentconstants.hxx>
      80             : #include <comphelper/sequenceashashmap.hxx>
      81             : 
      82             : using namespace std;
      83             : using namespace osl;
      84             : using namespace cppu;
      85             : using namespace ucbhelper;
      86             : using namespace com::sun::star;
      87             : using namespace com::sun::star::io;
      88             : using namespace com::sun::star::uno;
      89             : using namespace com::sun::star::ucb;
      90             : using namespace com::sun::star::util;
      91             : using namespace com::sun::star::lang;
      92             : using namespace com::sun::star::task;
      93             : using namespace com::sun::star::beans;
      94             : using namespace com::sun::star::packages;
      95             : using namespace com::sun::star::container;
      96             : using namespace com::sun::star::packages::zip;
      97             : using namespace com::sun::star::packages::manifest;
      98             : using namespace com::sun::star::packages::zip::ZipConstants;
      99             : 
     100             : #define LOGFILE_AUTHOR "mg115289"
     101             : 
     102             : //===========================================================================
     103             : 
     104           0 : class ActiveDataStreamer : public ::cppu::WeakImplHelper1< XActiveDataStreamer >
     105             : {
     106             :     uno::Reference< XStream > mStream;
     107             : public:
     108             : 
     109           0 :     virtual uno::Reference< XStream > SAL_CALL getStream()
     110             :             throw( RuntimeException )
     111           0 :             { return mStream; }
     112             : 
     113           0 :     virtual void SAL_CALL setStream( const uno::Reference< XStream >& stream )
     114             :             throw( RuntimeException )
     115           0 :             { mStream = stream; }
     116             : };
     117             : 
     118           0 : class DummyInputStream : public ::cppu::WeakImplHelper1< XInputStream >
     119             : {
     120           0 :     virtual sal_Int32 SAL_CALL readBytes( uno::Sequence< sal_Int8 >&, sal_Int32 )
     121             :             throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     122           0 :         { return 0; }
     123             : 
     124           0 :     virtual sal_Int32 SAL_CALL readSomeBytes( uno::Sequence< sal_Int8 >&, sal_Int32 )
     125             :             throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     126           0 :         { return 0; }
     127             : 
     128           0 :     virtual void SAL_CALL skipBytes( sal_Int32 )
     129             :             throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     130           0 :         {}
     131             : 
     132           0 :     virtual sal_Int32 SAL_CALL available()
     133             :             throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     134           0 :         { return 0; }
     135             : 
     136           0 :     virtual void SAL_CALL closeInput()
     137             :             throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     138           0 :         {}
     139             : };
     140             : 
     141             : //===========================================================================
     142             : 
     143        1016 : ZipPackage::ZipPackage ( const uno::Reference < XMultiServiceFactory > &xNewFactory )
     144        1016 : : m_aMutexHolder( new SotMutexHolder )
     145             : , m_nStartKeyGenerationID( xml::crypto::DigestID::SHA1 )
     146             : , m_nChecksumDigestID( xml::crypto::DigestID::SHA1_1K )
     147             : , m_nCommonEncryptionID( xml::crypto::CipherID::BLOWFISH_CFB_8 )
     148             : , m_bHasEncryptedEntries ( sal_False )
     149             : , m_bHasNonEncryptedEntries ( sal_False )
     150             : , m_bInconsistent ( sal_False )
     151             : , m_bForceRecovery ( sal_False )
     152             : , m_bMediaTypeFallbackUsed ( sal_False )
     153             : , m_nFormat( embed::StorageFormats::PACKAGE ) // package is the default format
     154             : , m_bAllowRemoveOnInsert( sal_True )
     155             : , m_eMode ( e_IMode_None )
     156             : , m_xFactory( xNewFactory )
     157             : , m_pRootFolder( NULL )
     158        2032 : , m_pZipFile( NULL )
     159             : {
     160        1016 :     m_xRootFolder = m_pRootFolder = new ZipPackageFolder( m_xFactory, m_nFormat, m_bAllowRemoveOnInsert );
     161        1016 : }
     162             : 
     163        2493 : ZipPackage::~ZipPackage( void )
     164             : {
     165         831 :     delete m_pZipFile;
     166             : 
     167             :     // All folders and streams contain pointers to their parents, when a parent diappeares
     168             :     // it should disconnect all the children from itself during destruction automatically.
     169             :     // So there is no need in explicit m_pRootFolder->releaseUpwardRef() call here any more
     170             :     // since m_pRootFolder has no parent and cleaning of it's children will be done automatically
     171             :     // during m_pRootFolder dieing by refcount.
     172        1662 : }
     173             : 
     174           0 : sal_Bool ZipPackage::isLocalFile() const
     175             : {
     176           0 :     OUString aSystemPath;
     177             :     uno::Reference< XUniversalContentBroker > xUcb(
     178             :         UniversalContentBroker::create(
     179           0 :             comphelper::getComponentContext( m_xFactory ) ) );
     180             :     try
     181             :     {
     182           0 :         aSystemPath = getSystemPathFromFileURL( xUcb, m_aURL );
     183             :     }
     184           0 :     catch ( Exception& )
     185             :     {
     186             :     }
     187           0 :     return !aSystemPath.isEmpty();
     188             : }
     189             : 
     190             : //--------------------------------------------------------
     191          67 : void ZipPackage::parseManifest()
     192             : {
     193          67 :     if ( m_nFormat == embed::StorageFormats::PACKAGE )
     194             :     {
     195          67 :         sal_Bool bManifestParsed = sal_False;
     196          67 :         bool bDifferentStartKeyAlgorithm = false;
     197          67 :         const OUString sMeta ("META-INF");
     198          67 :         if ( m_xRootFolder->hasByName( sMeta ) )
     199             :         {
     200          63 :             const OUString sManifest ("manifest.xml");
     201             : 
     202             :             try {
     203          63 :                 uno::Reference< XUnoTunnel > xTunnel;
     204          63 :                 Any aAny = m_xRootFolder->getByName( sMeta );
     205          63 :                 aAny >>= xTunnel;
     206          63 :                 uno::Reference< XNameContainer > xMetaInfFolder( xTunnel, UNO_QUERY );
     207          63 :                 if ( xMetaInfFolder.is() && xMetaInfFolder->hasByName( sManifest ) )
     208             :                 {
     209          63 :                     aAny = xMetaInfFolder->getByName( sManifest );
     210          63 :                     aAny >>= xTunnel;
     211          63 :                     uno::Reference < XActiveDataSink > xSink ( xTunnel, UNO_QUERY );
     212          63 :                     if ( xSink.is() )
     213             :                     {
     214          63 :                         uno::Reference < XManifestReader > xReader = ManifestReader::create( comphelper::getComponentContext( m_xFactory ) );
     215             : 
     216          63 :                         const OUString sPropFullPath ("FullPath");
     217          63 :                         const OUString sPropVersion ("Version");
     218          63 :                         const OUString sPropMediaType ("MediaType");
     219          63 :                         const OUString sPropInitialisationVector ("InitialisationVector");
     220          63 :                         const OUString sPropSalt ("Salt");
     221          63 :                         const OUString sPropIterationCount ("IterationCount");
     222          63 :                         const OUString sPropSize ("Size");
     223          63 :                         const OUString sPropDigest ("Digest");
     224          63 :                         const OUString sPropDerivedKeySize ("DerivedKeySize");
     225          63 :                         const OUString sPropDigestAlgorithm ("DigestAlgorithm");
     226          63 :                         const OUString sPropEncryptionAlgorithm ("EncryptionAlgorithm");
     227          63 :                         const OUString sPropStartKeyAlgorithm ("StartKeyAlgorithm");
     228             : 
     229          63 :                         uno::Sequence < uno::Sequence < PropertyValue > > aManifestSequence = xReader->readManifestSequence ( xSink->getInputStream() );
     230          63 :                         sal_Int32 nLength = aManifestSequence.getLength();
     231          63 :                         const uno::Sequence < PropertyValue > *pSequence = aManifestSequence.getConstArray();
     232          63 :                         ZipPackageStream *pStream = NULL;
     233          63 :                         ZipPackageFolder *pFolder = NULL;
     234             : 
     235         769 :                         for ( sal_Int32 i = 0; i < nLength ; i++, pSequence++ )
     236             :                         {
     237         706 :                             OUString sPath, sMediaType, sVersion;
     238         706 :                             const PropertyValue *pValue = pSequence->getConstArray();
     239         706 :                             const Any *pSalt = NULL, *pVector = NULL, *pCount = NULL, *pSize = NULL, *pDigest = NULL, *pDigestAlg = NULL, *pEncryptionAlg = NULL, *pStartKeyAlg = NULL, *pDerivedKeySize = NULL;
     240        2309 :                             for ( sal_Int32 j = 0, nNum = pSequence->getLength(); j < nNum; j++ )
     241             :                             {
     242        1603 :                                 if ( pValue[j].Name.equals( sPropFullPath ) )
     243         706 :                                     pValue[j].Value >>= sPath;
     244         897 :                                 else if ( pValue[j].Name.equals( sPropVersion ) )
     245          65 :                                     pValue[j].Value >>= sVersion;
     246         832 :                                 else if ( pValue[j].Name.equals( sPropMediaType ) )
     247         706 :                                     pValue[j].Value >>= sMediaType;
     248         126 :                                 else if ( pValue[j].Name.equals( sPropSalt ) )
     249          14 :                                     pSalt = &( pValue[j].Value );
     250         112 :                                 else if ( pValue[j].Name.equals( sPropInitialisationVector ) )
     251          14 :                                     pVector = &( pValue[j].Value );
     252          98 :                                 else if ( pValue[j].Name.equals( sPropIterationCount ) )
     253          14 :                                     pCount = &( pValue[j].Value );
     254          84 :                                 else if ( pValue[j].Name.equals( sPropSize ) )
     255          14 :                                     pSize = &( pValue[j].Value );
     256          70 :                                 else if ( pValue[j].Name.equals( sPropDigest ) )
     257          14 :                                     pDigest = &( pValue[j].Value );
     258          56 :                                 else if ( pValue[j].Name.equals( sPropDigestAlgorithm ) )
     259          14 :                                     pDigestAlg = &( pValue[j].Value );
     260          42 :                                 else if ( pValue[j].Name.equals( sPropEncryptionAlgorithm ) )
     261          14 :                                     pEncryptionAlg = &( pValue[j].Value );
     262          28 :                                 else if ( pValue[j].Name.equals( sPropStartKeyAlgorithm ) )
     263          14 :                                     pStartKeyAlg = &( pValue[j].Value );
     264          14 :                                 else if ( pValue[j].Name.equals( sPropDerivedKeySize ) )
     265          14 :                                     pDerivedKeySize = &( pValue[j].Value );
     266             :                             }
     267             : 
     268         706 :                             if ( !sPath.isEmpty() && hasByHierarchicalName ( sPath ) )
     269             :                             {
     270         706 :                                 aAny = getByHierarchicalName( sPath );
     271         706 :                                 uno::Reference < XUnoTunnel > xUnoTunnel;
     272         706 :                                 aAny >>= xUnoTunnel;
     273         706 :                                 sal_Int64 nTest=0;
     274         706 :                                 if ( (nTest = xUnoTunnel->getSomething( ZipPackageFolder::static_getImplementationId() )) != 0 )
     275             :                                 {
     276         239 :                                     pFolder = reinterpret_cast < ZipPackageFolder* > ( nTest );
     277         239 :                                     pFolder->SetMediaType ( sMediaType );
     278         239 :                                     pFolder->SetVersion ( sVersion );
     279             :                                 }
     280             :                                 else
     281             :                                 {
     282         467 :                                     pStream = reinterpret_cast < ZipPackageStream* > ( xUnoTunnel->getSomething( ZipPackageStream::static_getImplementationId() ));
     283         467 :                                     pStream->SetMediaType ( sMediaType );
     284         467 :                                     pStream->SetFromManifest( sal_True );
     285             : 
     286         467 :                                     if ( pSalt && pVector && pCount && pSize && pDigest && pDigestAlg && pEncryptionAlg )
     287             :                                     {
     288          14 :                                         uno::Sequence < sal_Int8 > aSequence;
     289          14 :                                         sal_Int64 nSize = 0;
     290          14 :                                         sal_Int32 nCount = 0, nDigestAlg = 0, nEncryptionAlg = 0;
     291          14 :                                         sal_Int32 nDerivedKeySize = 16, nStartKeyAlg = xml::crypto::DigestID::SHA1;
     292             : 
     293          14 :                                         pStream->SetToBeEncrypted ( sal_True );
     294             : 
     295          14 :                                         *pSalt >>= aSequence;
     296          14 :                                         pStream->setSalt ( aSequence );
     297             : 
     298          14 :                                         *pVector >>= aSequence;
     299          14 :                                         pStream->setInitialisationVector ( aSequence );
     300             : 
     301          14 :                                         *pCount >>= nCount;
     302          14 :                                         pStream->setIterationCount ( nCount );
     303             : 
     304          14 :                                         *pSize >>= nSize;
     305          14 :                                         pStream->setSize ( nSize );
     306             : 
     307          14 :                                         *pDigest >>= aSequence;
     308          14 :                                         pStream->setDigest ( aSequence );
     309             : 
     310          14 :                                         *pDigestAlg >>= nDigestAlg;
     311          14 :                                         pStream->SetImportedChecksumAlgorithm( nDigestAlg );
     312             : 
     313          14 :                                         *pEncryptionAlg >>= nEncryptionAlg;
     314          14 :                                         pStream->SetImportedEncryptionAlgorithm( nEncryptionAlg );
     315             : 
     316          14 :                                         if ( pDerivedKeySize )
     317          14 :                                             *pDerivedKeySize >>= nDerivedKeySize;
     318          14 :                                         pStream->SetImportedDerivedKeySize( nDerivedKeySize );
     319             : 
     320          14 :                                         if ( pStartKeyAlg )
     321          14 :                                             *pStartKeyAlg >>= nStartKeyAlg;
     322          14 :                                         pStream->SetImportedStartKeyAlgorithm( nStartKeyAlg );
     323             : 
     324          14 :                                         pStream->SetToBeCompressed ( sal_True );
     325          14 :                                         pStream->SetToBeEncrypted ( sal_True );
     326          14 :                                         pStream->SetIsEncrypted ( sal_True );
     327          14 :                                         if ( !m_bHasEncryptedEntries && pStream->getName() == "content.xml" )
     328             :                                         {
     329           3 :                                             m_bHasEncryptedEntries = sal_True;
     330           3 :                                             m_nStartKeyGenerationID = nStartKeyAlg;
     331           3 :                                             m_nChecksumDigestID = nDigestAlg;
     332           3 :                                             m_nCommonEncryptionID = nEncryptionAlg;
     333          14 :                                         }
     334             :                                     }
     335             :                                     else
     336         453 :                                         m_bHasNonEncryptedEntries = sal_True;
     337         706 :                                 }
     338             :                             }
     339         706 :                         }
     340             : 
     341          63 :                         bManifestParsed = sal_True;
     342             :                     }
     343             : 
     344             :                     // now hide the manifest.xml file from user
     345          63 :                     xMetaInfFolder->removeByName( sManifest );
     346          63 :                 }
     347             :             }
     348           0 :             catch( Exception& )
     349             :             {
     350           0 :                 if ( !m_bForceRecovery )
     351           0 :                     throw;
     352          63 :             }
     353             :         }
     354             : 
     355          67 :         if ( !bManifestParsed && !m_bForceRecovery )
     356             :             throw ZipIOException(
     357             :                 OSL_LOG_PREFIX "Could not parse manifest.xml\n",
     358           4 :                 uno::Reference< uno::XInterface >() );
     359             : 
     360          63 :         const OUString sMimetype ("mimetype");
     361          63 :         if ( m_xRootFolder->hasByName( sMimetype ) )
     362             :         {
     363             :             // get mediatype from the "mimetype" stream
     364          63 :             OUString aPackageMediatype;
     365          63 :             uno::Reference< lang::XUnoTunnel > xMimeTypeTunnel;
     366          63 :             m_xRootFolder->getByName( sMimetype ) >>= xMimeTypeTunnel;
     367          63 :             uno::Reference < io::XActiveDataSink > xMimeSink( xMimeTypeTunnel, UNO_QUERY );
     368          63 :             if ( xMimeSink.is() )
     369             :             {
     370          63 :                 uno::Reference< io::XInputStream > xMimeInStream = xMimeSink->getInputStream();
     371          63 :                 if ( xMimeInStream.is() )
     372             :                 {
     373             :                     // Mediatypes longer than 1024 symbols should not appear here
     374          63 :                     uno::Sequence< sal_Int8 > aData( 1024 );
     375          63 :                     sal_Int32 nRead = xMimeInStream->readBytes( aData, 1024 );
     376          63 :                     if ( nRead > aData.getLength() )
     377           0 :                         nRead = aData.getLength();
     378             : 
     379          63 :                     if ( nRead )
     380          63 :                         aPackageMediatype = OUString( ( sal_Char* )aData.getConstArray(), nRead, RTL_TEXTENCODING_ASCII_US );
     381          63 :                 }
     382             :             }
     383             : 
     384             : 
     385          63 :             if ( !bManifestParsed )
     386             :             {
     387             :                 // the manifest.xml could not be successfuly parsed, this is an inconsistent package
     388           0 :                 if ( aPackageMediatype.compareToAscii("application/vnd.") == 0 )
     389             :                 {
     390             :                     // accept only types that look similar to own mediatypes
     391           0 :                     m_pRootFolder->SetMediaType( aPackageMediatype );
     392           0 :                     m_bMediaTypeFallbackUsed = sal_True;
     393             :                 }
     394             :             }
     395          63 :             else if ( !m_bForceRecovery )
     396             :             {
     397             :                 // the mimetype stream should contain the information from manifest.xml
     398          63 :                 if ( !m_pRootFolder->GetMediaType().equals( aPackageMediatype ) )
     399             :                     throw ZipIOException(
     400             :                         OSL_LOG_PREFIX "mimetype conflicts with manifest.xml\n",
     401           0 :                         uno::Reference< uno::XInterface >() );
     402             :             }
     403             : 
     404          63 :             m_xRootFolder->removeByName( sMimetype );
     405             :         }
     406             : 
     407          63 :         m_bInconsistent = m_pRootFolder->LookForUnexpectedODF12Streams( OUString() );
     408             : 
     409          63 :         sal_Bool bODF12AndNewer = ( m_pRootFolder->GetVersion().compareTo( ODFVER_012_TEXT ) >= 0 );
     410          63 :         if ( !m_bForceRecovery && bODF12AndNewer )
     411             :         {
     412          62 :             if ( m_bInconsistent )
     413             :             {
     414             :                 // this is an ODF1.2 document that contains streams not referred in the manifest.xml;
     415             :                 // in case of ODF1.2 documents without version in manifest.xml the property IsInconsistent
     416             :                 // should be checked later
     417             :                 throw ZipIOException(
     418             :                     OSL_LOG_PREFIX "there are streams not referred in manifest.xml\n",
     419           0 :                     uno::Reference< uno::XInterface >() );
     420             :             }
     421             :             else if ( bDifferentStartKeyAlgorithm )
     422             :             {
     423             :                 // all the streams should be encrypted with the same StartKey in ODF1.2
     424             :                 // TODO/LATER: in future the exception should be thrown
     425             :                 OSL_ENSURE( false, "ODF1.2 contains different StartKey Algorithms" );
     426             :                 // throw ZipIOException( OSL_LOG_PREFIX "More than one Start Key Generation algorithm is specified!", uno::Reference< uno::XInterface >() );
     427             :             }
     428             :         }
     429             : 
     430             :         // in case it is a correct ODF1.2 document, the version must be set
     431             :         // and the META-INF folder is reserved for package format
     432          63 :         if ( bODF12AndNewer )
     433          62 :             m_xRootFolder->removeByName( sMeta );
     434             :     }
     435          63 : }
     436             : 
     437             : //--------------------------------------------------------
     438         199 : void ZipPackage::parseContentType()
     439             : {
     440         199 :     if ( m_nFormat == embed::StorageFormats::OFOPXML )
     441             :     {
     442         199 :         const OUString aContentTypes("[Content_Types].xml");
     443             :         try {
     444             :             // the content type must exist in OFOPXML format!
     445         199 :             if ( !m_xRootFolder->hasByName( aContentTypes ) )
     446             :                 throw io::IOException(OSL_LOG_PREFIX "Wrong format!",
     447           0 :                                         uno::Reference< uno::XInterface >() );
     448             : 
     449         199 :             uno::Reference< lang::XUnoTunnel > xTunnel;
     450         199 :             uno::Any aAny = m_xRootFolder->getByName( aContentTypes );
     451         199 :             aAny >>= xTunnel;
     452         199 :             uno::Reference < io::XActiveDataSink > xSink( xTunnel, UNO_QUERY );
     453         199 :             if ( xSink.is() )
     454             :             {
     455         199 :                 uno::Reference< io::XInputStream > xInStream = xSink->getInputStream();
     456         199 :                 if ( xInStream.is() )
     457             :                 {
     458         199 :                     sal_Int32 nInd = 0;
     459             :                     // here aContentTypeInfo[0] - Defaults, and aContentTypeInfo[1] - Overrides
     460             :                     uno::Sequence< uno::Sequence< beans::StringPair > > aContentTypeInfo =
     461         199 :                         ::comphelper::OFOPXMLHelper::ReadContentTypeSequence( xInStream, comphelper::getComponentContext(m_xFactory) );
     462             : 
     463         199 :                     if ( aContentTypeInfo.getLength() != 2 )
     464           0 :                         throw io::IOException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     465             : 
     466             :                     // set the implicit types fist
     467         440 :                     for ( nInd = 0; nInd < aContentTypeInfo[0].getLength(); nInd++ )
     468         241 :                         m_pRootFolder->setChildStreamsTypeByExtension( aContentTypeInfo[0][nInd] );
     469             : 
     470             :                     // now set the explicit types
     471        1987 :                     for ( nInd = 0; nInd < aContentTypeInfo[1].getLength(); nInd++ )
     472             :                     {
     473        1788 :                         OUString aPath;
     474        1788 :                         if ( aContentTypeInfo[1][nInd].First.toChar() == ( sal_Unicode )'/' )
     475        1788 :                             aPath = aContentTypeInfo[1][nInd].First.copy( 1 );
     476             :                         else
     477           0 :                             aPath = aContentTypeInfo[1][nInd].First;
     478             : 
     479        1788 :                         if ( !aPath.isEmpty() && hasByHierarchicalName( aPath ) )
     480             :                         {
     481        1786 :                             uno::Any aIterAny = getByHierarchicalName( aPath );
     482        1786 :                             uno::Reference < lang::XUnoTunnel > xIterTunnel;
     483        1786 :                             aIterAny >>= xIterTunnel;
     484        1786 :                             sal_Int64 nTest = xIterTunnel->getSomething( ZipPackageStream::static_getImplementationId() );
     485        1786 :                             if ( nTest != 0 )
     486             :                             {
     487             :                                 // this is a package stream, in OFOPXML format only streams can have mediatype
     488        1786 :                                 ZipPackageStream *pStream = reinterpret_cast < ZipPackageStream* > ( nTest );
     489        1786 :                                 pStream->SetMediaType( aContentTypeInfo[1][nInd].Second );
     490        1786 :                             }
     491             :                         }
     492        1987 :                     }
     493         199 :                 }
     494             :             }
     495             : 
     496         199 :             m_xRootFolder->removeByName( aContentTypes );
     497             :         }
     498           0 :         catch( uno::Exception& )
     499             :         {
     500           0 :             if ( !m_bForceRecovery )
     501           0 :                 throw;
     502         199 :         }
     503             :     }
     504         199 : }
     505             : 
     506             : //--------------------------------------------------------
     507         420 : void ZipPackage::getZipFileContents()
     508             : {
     509         420 :     auto_ptr < ZipEnumeration > pEnum ( m_pZipFile->entries() );
     510             :     ZipPackageStream *pPkgStream;
     511             :     ZipPackageFolder *pPkgFolder, *pCurrent;
     512         420 :     OUString sTemp, sDirName;
     513             :     sal_Int32 nOldIndex, nIndex, nStreamIndex;
     514         420 :     FolderHash::iterator aIter;
     515             : 
     516        6494 :     while ( pEnum->hasMoreElements() )
     517             :     {
     518        5654 :         nIndex = nOldIndex = 0;
     519        5654 :         pCurrent = m_pRootFolder;
     520        5654 :         const ZipEntry & rEntry = *pEnum->nextElement();
     521        5654 :         OUString rName = rEntry.sPath;
     522             : 
     523        5654 :         if ( m_bForceRecovery )
     524             :         {
     525             :             // the PKZIP Application note version 6.2 does not allows to use '\' as separator
     526             :             // unfortunately it is used by some implementations, so we have to support it in recovery mode
     527           0 :             rName = rName.replace( '\\', '/' );
     528             :         }
     529             : 
     530        5654 :         nStreamIndex = rName.lastIndexOf ( '/' );
     531        5654 :         if ( nStreamIndex != -1 )
     532             :         {
     533        4849 :             sDirName = rName.copy ( 0, nStreamIndex );
     534        4849 :             aIter = m_aRecent.find ( sDirName );
     535        4849 :             if ( aIter != m_aRecent.end() )
     536        2196 :                 pCurrent = ( *aIter ).second;
     537             :         }
     538             : 
     539        5654 :         if ( pCurrent == m_pRootFolder )
     540             :         {
     541       11160 :             while ( ( nIndex = rName.indexOf( '/', nOldIndex ) ) != -1 )
     542             :             {
     543        4244 :                 sTemp = rName.copy ( nOldIndex, nIndex - nOldIndex );
     544        4244 :                 if ( nIndex == nOldIndex )
     545           0 :                     break;
     546        4244 :                 if ( !pCurrent->hasByName( sTemp ) )
     547             :                 {
     548        2813 :                     pPkgFolder = new ZipPackageFolder( m_xFactory, m_nFormat, m_bAllowRemoveOnInsert );
     549        2813 :                     pPkgFolder->setName( sTemp );
     550        2813 :                     pPkgFolder->doSetParent( pCurrent, sal_True );
     551        2813 :                     pCurrent = pPkgFolder;
     552             :                 }
     553             :                 else
     554        1431 :                     pCurrent = pCurrent->doGetByName( sTemp ).pFolder;
     555        4244 :                 nOldIndex = nIndex+1;
     556             :             }
     557        3458 :             if ( nStreamIndex != -1 && !sDirName.isEmpty() )
     558        2653 :                 m_aRecent [ sDirName ] = pCurrent;
     559             :         }
     560        5654 :         if ( rName.getLength() -1 != nStreamIndex )
     561             :         {
     562        4859 :             nStreamIndex++;
     563        4859 :             sTemp = rName.copy( nStreamIndex, rName.getLength() - nStreamIndex );
     564        4859 :             pPkgStream = new ZipPackageStream( *this, m_xFactory, m_bAllowRemoveOnInsert );
     565        4859 :             pPkgStream->SetPackageMember( sal_True );
     566        4859 :             pPkgStream->setZipEntryOnLoading( rEntry );
     567        4859 :             pPkgStream->setName( sTemp );
     568        4859 :             pPkgStream->doSetParent( pCurrent, sal_True );
     569             :         }
     570        5654 :     }
     571             : 
     572         420 :     if ( m_nFormat == embed::StorageFormats::PACKAGE )
     573          67 :         parseManifest();
     574         353 :     else if ( m_nFormat == embed::StorageFormats::OFOPXML )
     575         203 :         parseContentType();
     576         416 : }
     577             : 
     578             : //--------------------------------------------------------
     579        1016 : void SAL_CALL ZipPackage::initialize( const uno::Sequence< Any >& aArguments )
     580             :         throw( Exception, RuntimeException )
     581             : {
     582             :     RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "{ ZipPackage::initialize" );
     583        1016 :     sal_Bool bBadZipFile = sal_False, bHaveZipFile = sal_True;
     584        1016 :     uno::Reference< XProgressHandler > xProgressHandler;
     585        1016 :     beans::NamedValue aNamedValue;
     586             : 
     587        1016 :     if ( aArguments.getLength() )
     588             :     {
     589        3451 :         for( int ind = 0; ind < aArguments.getLength(); ind++ )
     590             :         {
     591        2435 :             OUString aParamUrl;
     592        2435 :             if ( ( aArguments[ind] >>= aParamUrl ))
     593             :             {
     594           0 :                 m_eMode = e_IMode_URL;
     595             :                 try
     596             :                 {
     597           0 :                     sal_Int32 nParam = aParamUrl.indexOf( '?' );
     598           0 :                     if ( nParam >= 0 )
     599             :                     {
     600           0 :                         m_aURL = aParamUrl.copy( 0, nParam );
     601           0 :                         OUString aParam = aParamUrl.copy( nParam + 1 );
     602             : 
     603           0 :                           sal_Int32 nIndex = 0;
     604           0 :                         do
     605             :                         {
     606           0 :                             OUString aCommand = aParam.getToken( 0, '&', nIndex );
     607           0 :                             if ( aCommand == "repairpackage" )
     608             :                             {
     609           0 :                                 m_bForceRecovery = sal_True;
     610             :                                 break;
     611             :                             }
     612           0 :                             else if ( aCommand == "purezip" )
     613             :                             {
     614           0 :                                 m_nFormat = embed::StorageFormats::ZIP;
     615           0 :                                 m_pRootFolder->setPackageFormat_Impl( m_nFormat );
     616             :                                 break;
     617             :                             }
     618           0 :                             else if ( aCommand == "ofopxml" )
     619             :                             {
     620           0 :                                 m_nFormat = embed::StorageFormats::OFOPXML;
     621           0 :                                 m_pRootFolder->setPackageFormat_Impl( m_nFormat );
     622             :                                 break;
     623           0 :                             }
     624             :                         }
     625           0 :                         while ( nIndex >= 0 );
     626             :                     }
     627             :                     else
     628           0 :                         m_aURL = aParamUrl;
     629             : 
     630             :                     Content aContent(
     631             :                         m_aURL, uno::Reference< XCommandEnvironment >(),
     632           0 :                         comphelper::getComponentContext( m_xFactory ) );
     633           0 :                     Any aAny = aContent.getPropertyValue("Size");
     634           0 :                     sal_uInt64 aSize = 0;
     635             :                     // kind of optimisation: treat empty files as nonexistent files
     636             :                     // and write to such files directly. Note that "Size" property is optional.
     637           0 :                     bool bHasSizeProperty = aAny >>= aSize;
     638           0 :                     if( !bHasSizeProperty || ( bHasSizeProperty && aSize ) )
     639             :                     {
     640           0 :                         uno::Reference < XActiveDataSink > xSink = new ZipPackageSink;
     641           0 :                         if ( aContent.openStream ( xSink ) )
     642           0 :                             m_xContentStream = xSink->getInputStream();
     643             :                     }
     644             :                     else
     645           0 :                         bHaveZipFile = sal_False;
     646             :                 }
     647           0 :                 catch ( com::sun::star::uno::Exception& )
     648             :                 {
     649             :                     // Exception derived from uno::Exception thrown. This probably
     650             :                     // means the file doesn't exist...we'll create it at
     651             :                     // commitChanges time
     652           0 :                     bHaveZipFile = sal_False;
     653             :                 }
     654             :             }
     655        2435 :             else if ( ( aArguments[ind] >>= m_xStream ) )
     656             :             {
     657             :                 // a writable stream can implement both XStream & XInputStream
     658        1016 :                 m_eMode = e_IMode_XStream;
     659        1016 :                 m_xContentStream = m_xStream->getInputStream();
     660             :             }
     661        1419 :             else if ( ( aArguments[ind] >>= m_xContentStream ) )
     662             :             {
     663           0 :                 m_eMode = e_IMode_XInputStream;
     664             :             }
     665        1419 :             else if ( ( aArguments[ind] >>= aNamedValue ) )
     666             :             {
     667        1419 :                 if ( aNamedValue.Name == "RepairPackage" )
     668          25 :                     aNamedValue.Value >>= m_bForceRecovery;
     669        1394 :                 else if ( aNamedValue.Name == "PackageFormat" )
     670             :                 {
     671             :                     // setting this argument to true means Package format
     672             :                     // setting it to false means plain Zip format
     673             : 
     674           0 :                     sal_Bool bPackFormat = sal_True;
     675           0 :                     aNamedValue.Value >>= bPackFormat;
     676           0 :                     if ( !bPackFormat )
     677           0 :                         m_nFormat = embed::StorageFormats::ZIP;
     678             : 
     679           0 :                     m_pRootFolder->setPackageFormat_Impl( m_nFormat );
     680             :                 }
     681        1394 :                 else if ( aNamedValue.Name == "StorageFormat" )
     682             :                 {
     683         378 :                     OUString aFormatName;
     684         378 :                     sal_Int32 nFormatID = 0;
     685         378 :                     if ( aNamedValue.Value >>= aFormatName )
     686             :                     {
     687         378 :                         if ( aFormatName.equals( PACKAGE_STORAGE_FORMAT_STRING ) )
     688           0 :                             m_nFormat = embed::StorageFormats::PACKAGE;
     689         378 :                         else if ( aFormatName.equals( ZIP_STORAGE_FORMAT_STRING ) )
     690         154 :                             m_nFormat = embed::StorageFormats::ZIP;
     691         224 :                         else if ( aFormatName.equals( OFOPXML_STORAGE_FORMAT_STRING ) )
     692         224 :                             m_nFormat = embed::StorageFormats::OFOPXML;
     693             :                         else
     694           0 :                             throw lang::IllegalArgumentException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 );
     695             :                     }
     696           0 :                     else if ( aNamedValue.Value >>= nFormatID )
     697             :                     {
     698           0 :                         if ( nFormatID != embed::StorageFormats::PACKAGE
     699             :                           && nFormatID != embed::StorageFormats::ZIP
     700             :                           && nFormatID != embed::StorageFormats::OFOPXML )
     701           0 :                             throw lang::IllegalArgumentException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 );
     702             : 
     703           0 :                         m_nFormat = nFormatID;
     704             :                     }
     705             :                     else
     706           0 :                         throw lang::IllegalArgumentException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 );
     707             : 
     708         378 :                     m_pRootFolder->setPackageFormat_Impl( m_nFormat );
     709             :                 }
     710        1016 :                 else if ( aNamedValue.Name == "AllowRemoveOnInsert" )
     711             :                 {
     712        1016 :                     aNamedValue.Value >>= m_bAllowRemoveOnInsert;
     713        1016 :                     m_pRootFolder->setRemoveOnInsertMode_Impl( m_bAllowRemoveOnInsert );
     714             :                 }
     715             : 
     716             :                 // for now the progress handler is not used, probably it will never be
     717             :                 // if ( aNamedValue.Name == "ProgressHandler" )
     718             :             }
     719             :             else
     720             :             {
     721             :                 // The URL is not acceptable
     722             :                 throw com::sun::star::uno::Exception (OSL_LOG_PREFIX "Bad arguments.",
     723           0 :                     static_cast < ::cppu::OWeakObject * > ( this ) );
     724             :             }
     725        2435 :         }
     726             : 
     727             :         try
     728             :         {
     729        1016 :             if ( m_xContentStream.is() )
     730             :             {
     731             :                 // the stream must be seekable, if it is not it will be wrapped
     732        1016 :                 m_xContentStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( m_xContentStream, comphelper::getComponentContext( m_xFactory ) );
     733        1016 :                 m_xContentSeek = uno::Reference < XSeekable > ( m_xContentStream, UNO_QUERY );
     734        1016 :                 if ( ! m_xContentSeek.is() )
     735             :                     throw com::sun::star::uno::Exception (OSL_LOG_PREFIX "The package component _requires_ an XSeekable interface!",
     736           0 :                             static_cast < ::cppu::OWeakObject * > ( this ) );
     737             : 
     738        1016 :                 if ( !m_xContentSeek->getLength() )
     739         596 :                     bHaveZipFile = sal_False;
     740             :             }
     741             :             else
     742           0 :                 bHaveZipFile = sal_False;
     743             :         }
     744           0 :         catch ( com::sun::star::uno::Exception& )
     745             :         {
     746             :             // Exception derived from uno::Exception thrown. This probably
     747             :             // means the file doesn't exist...we'll create it at
     748             :             // commitChanges time
     749           0 :             bHaveZipFile = sal_False;
     750             :         }
     751        1016 :         if ( bHaveZipFile )
     752             :         {
     753             :             try
     754             :             {
     755         420 :                 m_pZipFile = new ZipFile ( m_xContentStream, comphelper::getComponentContext(m_xFactory), sal_True, m_bForceRecovery, xProgressHandler );
     756         420 :                 getZipFileContents();
     757             :             }
     758           8 :             catch ( IOException & )
     759             :             {
     760           4 :                 bBadZipFile = sal_True;
     761             :             }
     762           0 :             catch ( ZipException & )
     763             :             {
     764           0 :                 bBadZipFile = sal_True;
     765             :             }
     766           0 :             catch ( Exception & )
     767             :             {
     768           0 :                 if( m_pZipFile ) { delete m_pZipFile; m_pZipFile = NULL; }
     769           0 :                 throw;
     770             :             }
     771             : 
     772         420 :             if ( bBadZipFile )
     773             :             {
     774             :                 // clean up the memory, and tell the UCB about the error
     775           4 :                 if( m_pZipFile ) { delete m_pZipFile; m_pZipFile = NULL; }
     776             : 
     777             :                 throw com::sun::star::packages::zip::ZipIOException (
     778             :                     OSL_LOG_PREFIX "Bad Zip File.",
     779           4 :                     static_cast < ::cppu::OWeakObject * > ( this ) );
     780             :             }
     781             :         }
     782             :     }
     783             : 
     784        1016 :     RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "} ZipPackage::initialize" );
     785        1012 : }
     786             : 
     787             : //--------------------------------------------------------
     788        3504 : Any SAL_CALL ZipPackage::getByHierarchicalName( const OUString& aName )
     789             :         throw( NoSuchElementException, RuntimeException )
     790             : {
     791        3504 :     OUString sTemp, sDirName;
     792             :     sal_Int32 nOldIndex, nIndex, nStreamIndex;
     793        3504 :     FolderHash::iterator aIter;
     794             : 
     795        3504 :     if ( ( nIndex = aName.getLength() ) == 1 && *aName.getStr() == '/' )
     796        1075 :         return makeAny ( uno::Reference < XUnoTunnel > ( m_pRootFolder ) );
     797             :     else
     798             :     {
     799        2429 :         nStreamIndex = aName.lastIndexOf ( '/' );
     800        2429 :         bool bFolder = nStreamIndex == nIndex-1;
     801        2429 :         if ( nStreamIndex != -1 )
     802             :         {
     803        2134 :             sDirName = aName.copy ( 0, nStreamIndex );
     804        2134 :             aIter = m_aRecent.find ( sDirName );
     805        2134 :             if ( aIter != m_aRecent.end() )
     806             :             {
     807        2134 :                 if ( bFolder )
     808             :                 {
     809         176 :                     sal_Int32 nDirIndex = aName.lastIndexOf ( '/', nStreamIndex );
     810         176 :                     sTemp = aName.copy ( nDirIndex == -1 ? 0 : nDirIndex+1, nStreamIndex-nDirIndex-1 );
     811         176 :                     if ( sTemp == ( *aIter ).second->getName() )
     812         105 :                         return makeAny ( uno::Reference < XUnoTunnel > ( ( *aIter ).second ) );
     813             :                     else
     814          71 :                         m_aRecent.erase ( aIter );
     815             :                 }
     816             :                 else
     817             :                 {
     818        1958 :                     sTemp = aName.copy ( nStreamIndex + 1 );
     819        1958 :                     if ( ( *aIter ).second->hasByName( sTemp ) )
     820        1958 :                         return ( *aIter ).second->getByName( sTemp );
     821             :                     else
     822           0 :                         m_aRecent.erase( aIter );
     823             :                 }
     824             :             }
     825             :         }
     826             :         else
     827             :         {
     828         295 :             if ( m_pRootFolder->hasByName ( aName ) )
     829         295 :                 return m_pRootFolder->getByName ( aName );
     830             :         }
     831          71 :         nOldIndex = 0;
     832          71 :         ZipPackageFolder * pCurrent = m_pRootFolder;
     833          71 :         ZipPackageFolder * pPrevious = NULL;
     834         225 :         while ( ( nIndex = aName.indexOf( '/', nOldIndex )) != -1 )
     835             :         {
     836          83 :             sTemp = aName.copy ( nOldIndex, nIndex - nOldIndex );
     837          83 :             if ( nIndex == nOldIndex )
     838           0 :                 break;
     839          83 :             if ( pCurrent->hasByName( sTemp ) )
     840             :             {
     841          83 :                 pPrevious = pCurrent;
     842          83 :                 pCurrent = pCurrent->doGetByName( sTemp ).pFolder;
     843             :             }
     844             :             else
     845           0 :                 throw NoSuchElementException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     846          83 :             nOldIndex = nIndex+1;
     847             :         }
     848          71 :         if ( bFolder )
     849             :         {
     850          71 :             if ( nStreamIndex != -1 )
     851          71 :                 m_aRecent[sDirName] = pPrevious;
     852          71 :             return makeAny ( uno::Reference < XUnoTunnel > ( pCurrent ) );
     853             :         }
     854             :         else
     855             :         {
     856           0 :             sTemp = aName.copy( nOldIndex, aName.getLength() - nOldIndex );
     857           0 :             if ( pCurrent->hasByName ( sTemp ) )
     858             :             {
     859           0 :                 if ( nStreamIndex != -1 )
     860           0 :                     m_aRecent[sDirName] = pCurrent;
     861           0 :                 return pCurrent->getByName( sTemp );
     862             :             }
     863             :             else
     864           0 :                 throw NoSuchElementException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     865             :         }
     866        3504 :     }
     867             : }
     868             : 
     869             : //--------------------------------------------------------
     870        2494 : sal_Bool SAL_CALL ZipPackage::hasByHierarchicalName( const OUString& aName )
     871             :         throw( RuntimeException )
     872             : {
     873        2494 :     OUString sTemp, sDirName;
     874             :     sal_Int32 nOldIndex, nIndex, nStreamIndex;
     875        2494 :     FolderHash::iterator aIter;
     876             : 
     877        2494 :     if ( ( nIndex = aName.getLength() ) == 1 && *aName.getStr() == '/' )
     878          63 :         return sal_True;
     879             :     else
     880             :     {
     881        2431 :         nStreamIndex = aName.lastIndexOf ( '/' );
     882        2431 :         bool bFolder = nStreamIndex == nIndex-1;
     883        2431 :         if ( nStreamIndex != -1 )
     884             :         {
     885        2136 :             sDirName = aName.copy ( 0, nStreamIndex );
     886        2136 :             aIter = m_aRecent.find ( sDirName );
     887        2136 :             if ( aIter != m_aRecent.end() )
     888             :             {
     889        2065 :                 if ( bFolder )
     890             :                 {
     891         105 :                     sal_Int32 nDirIndex = aName.lastIndexOf ( '/', nStreamIndex );
     892         105 :                     sTemp = aName.copy ( nDirIndex == -1 ? 0 : nDirIndex+1, nStreamIndex-nDirIndex-1 );
     893         105 :                     if ( sTemp == ( *aIter ).second->getName() )
     894         105 :                         return sal_True;
     895             :                     else
     896           0 :                         m_aRecent.erase ( aIter );
     897             :                 }
     898             :                 else
     899             :                 {
     900        1960 :                     sTemp = aName.copy ( nStreamIndex + 1 );
     901        1960 :                     if ( ( *aIter ).second->hasByName( sTemp ) )
     902        1958 :                         return sal_True;
     903             :                     else
     904           2 :                         m_aRecent.erase( aIter );
     905             :                 }
     906             :             }
     907             :         }
     908             :         else
     909             :         {
     910         295 :             if ( m_pRootFolder->hasByName ( aName ) )
     911         295 :                 return sal_True;
     912             :         }
     913          73 :         ZipPackageFolder * pCurrent = m_pRootFolder;
     914          73 :         ZipPackageFolder * pPrevious = NULL;
     915          73 :         nOldIndex = 0;
     916         233 :         while ( ( nIndex = aName.indexOf( '/', nOldIndex )) != -1 )
     917             :         {
     918          87 :             sTemp = aName.copy ( nOldIndex, nIndex - nOldIndex );
     919          87 :             if ( nIndex == nOldIndex )
     920           0 :                 break;
     921          87 :             if ( pCurrent->hasByName( sTemp ) )
     922             :             {
     923          87 :                 pPrevious = pCurrent;
     924          87 :                 pCurrent = pCurrent->doGetByName( sTemp ).pFolder;
     925             :             }
     926             :             else
     927           0 :                 return sal_False;
     928          87 :             nOldIndex = nIndex+1;
     929             :         }
     930          73 :         if ( bFolder )
     931             :         {
     932          71 :             m_aRecent[sDirName] = pPrevious;
     933          71 :             return sal_True;
     934             :         }
     935             :         else
     936             :         {
     937           2 :             sTemp = aName.copy( nOldIndex, aName.getLength() - nOldIndex );
     938             : 
     939           2 :             if ( pCurrent->hasByName( sTemp ) )
     940             :             {
     941           0 :                 m_aRecent[sDirName] = pCurrent;
     942           0 :                 return sal_True;
     943             :             }
     944             :         }
     945           2 :         return sal_False;
     946        2494 :     }
     947             : }
     948             : 
     949             : //--------------------------------------------------------
     950           0 : uno::Reference< XInterface > SAL_CALL ZipPackage::createInstance()
     951             :         throw( Exception, RuntimeException )
     952             : {
     953           0 :     uno::Reference < XInterface > xRef = *( new ZipPackageStream ( *this, m_xFactory, m_bAllowRemoveOnInsert ) );
     954           0 :     return xRef;
     955             : }
     956             : //--------------------------------------------------------
     957        8584 : uno::Reference< XInterface > SAL_CALL ZipPackage::createInstanceWithArguments( const uno::Sequence< Any >& aArguments )
     958             :         throw( Exception, RuntimeException )
     959             : {
     960        8584 :     sal_Bool bArg = sal_False;
     961        8584 :     uno::Reference < XInterface > xRef;
     962        8584 :     if ( aArguments.getLength() )
     963        8584 :         aArguments[0] >>= bArg;
     964        8584 :     if ( bArg )
     965        6617 :         xRef = *new ZipPackageFolder ( m_xFactory, m_nFormat, m_bAllowRemoveOnInsert );
     966             :     else
     967        1967 :         xRef = *new ZipPackageStream ( *this, m_xFactory, m_bAllowRemoveOnInsert );
     968             : 
     969        8584 :     return xRef;
     970             : }
     971             : 
     972             : //--------------------------------------------------------
     973           8 : void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut )
     974             : {
     975           8 :     const OUString sMime ("mimetype");
     976           8 :     if ( m_xRootFolder->hasByName( sMime ) )
     977           0 :         m_xRootFolder->removeByName( sMime );
     978             : 
     979           8 :     ZipEntry * pEntry = new ZipEntry;
     980           8 :     sal_Int32 nBufferLength = m_pRootFolder->GetMediaType().getLength();
     981           8 :     OString sMediaType = OUStringToOString( m_pRootFolder->GetMediaType(), RTL_TEXTENCODING_ASCII_US );
     982           8 :     uno::Sequence< sal_Int8 > aType( ( sal_Int8* )sMediaType.getStr(),
     983           8 :                                      nBufferLength );
     984             : 
     985             : 
     986           8 :     pEntry->sPath = sMime;
     987           8 :     pEntry->nMethod = STORED;
     988           8 :     pEntry->nSize = pEntry->nCompressedSize = nBufferLength;
     989           8 :     pEntry->nTime = ZipOutputStream::getCurrentDosTime();
     990             : 
     991           8 :     CRC32 aCRC32;
     992           8 :     aCRC32.update( aType );
     993           8 :     pEntry->nCrc = aCRC32.getValue();
     994             : 
     995             :     try
     996             :     {
     997           8 :         aZipOut.putNextEntry( *pEntry, NULL );
     998           8 :         aZipOut.write( aType, 0, nBufferLength );
     999           8 :         aZipOut.closeEntry();
    1000             :     }
    1001           0 :     catch ( const ::com::sun::star::io::IOException & r )
    1002             :     {
    1003             :         throw WrappedTargetException(
    1004             :                 OSL_LOG_PREFIX "Error adding mimetype to the ZipOutputStream!",
    1005             :                 static_cast < OWeakObject * > ( this ),
    1006           0 :                 makeAny( r ) );
    1007           8 :     }
    1008           8 : }
    1009             : 
    1010             : //--------------------------------------------------------
    1011           8 : void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< uno::Sequence < PropertyValue > >& aManList )
    1012             : {
    1013             :     // Write the manifest
    1014           8 :     uno::Reference < XManifestWriter > xWriter = ManifestWriter::create( comphelper::getComponentContext(m_xFactory) );
    1015           8 :     ZipEntry * pEntry = new ZipEntry;
    1016           8 :     ZipPackageBuffer *pBuffer = new ZipPackageBuffer( n_ConstBufferSize );
    1017           8 :     uno::Reference < XOutputStream > xManOutStream( *pBuffer, UNO_QUERY );
    1018             : 
    1019           8 :     pEntry->sPath = "META-INF/manifest.xml";
    1020           8 :     pEntry->nMethod = DEFLATED;
    1021           8 :     pEntry->nCrc = -1;
    1022           8 :     pEntry->nSize = pEntry->nCompressedSize = -1;
    1023           8 :     pEntry->nTime = ZipOutputStream::getCurrentDosTime();
    1024             : 
    1025             :     // Convert vector into a uno::Sequence
    1026           8 :     uno::Sequence < uno::Sequence < PropertyValue > > aManifestSequence ( aManList.size() );
    1027           8 :     sal_Int32 nInd = 0;
    1028          52 :     for ( vector < uno::Sequence < PropertyValue > >::const_iterator aIter = aManList.begin(), aEnd = aManList.end();
    1029             :          aIter != aEnd;
    1030             :          ++aIter, ++nInd )
    1031             :     {
    1032          44 :         aManifestSequence[nInd] = ( *aIter );
    1033             :     }
    1034           8 :     xWriter->writeManifestSequence ( xManOutStream,  aManifestSequence );
    1035             : 
    1036           8 :     sal_Int32 nBufferLength = static_cast < sal_Int32 > ( pBuffer->getPosition() );
    1037           8 :     pBuffer->realloc( nBufferLength );
    1038             : 
    1039             :     // the manifest.xml is never encrypted - so pass an empty reference
    1040           8 :     aZipOut.putNextEntry( *pEntry, NULL );
    1041           8 :     aZipOut.write( pBuffer->getSequence(), 0, nBufferLength );
    1042           8 :     aZipOut.closeEntry();
    1043           8 : }
    1044             : 
    1045             : //--------------------------------------------------------
    1046          25 : void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno::Sequence < PropertyValue > >& aManList )
    1047             : {
    1048          25 :     const OUString sFullPath ("FullPath");
    1049          25 :     const OUString sMediaType ("MediaType");
    1050             : 
    1051          25 :     ZipEntry* pEntry = new ZipEntry;
    1052          25 :     ZipPackageBuffer *pBuffer = new ZipPackageBuffer( n_ConstBufferSize );
    1053          25 :     uno::Reference< io::XOutputStream > xConTypeOutStream( *pBuffer, UNO_QUERY );
    1054             : 
    1055          25 :     pEntry->sPath = "[Content_Types].xml";
    1056          25 :     pEntry->nMethod = DEFLATED;
    1057          25 :     pEntry->nCrc = -1;
    1058          25 :     pEntry->nSize = pEntry->nCompressedSize = -1;
    1059          25 :     pEntry->nTime = ZipOutputStream::getCurrentDosTime();
    1060             : 
    1061             :     // Convert vector into a uno::Sequence
    1062             :     // TODO/LATER: use Defaulst entries in future
    1063          25 :     uno::Sequence< beans::StringPair > aDefaultsSequence;
    1064          25 :     uno::Sequence< beans::StringPair > aOverridesSequence( aManList.size() );
    1065          25 :     sal_Int32 nSeqLength = 0;
    1066         252 :     for ( vector< uno::Sequence< beans::PropertyValue > >::const_iterator aIter = aManList.begin(),
    1067          25 :             aEnd = aManList.end();
    1068             :          aIter != aEnd;
    1069             :          ++aIter)
    1070             :     {
    1071         202 :         OUString aPath;
    1072         202 :         OUString aType;
    1073             :         OSL_ENSURE( ( *aIter )[PKG_MNFST_MEDIATYPE].Name.equals( sMediaType ) && ( *aIter )[PKG_MNFST_FULLPATH].Name.equals( sFullPath ),
    1074             :                     "The mediatype sequence format is wrong!\n" );
    1075         202 :         ( *aIter )[PKG_MNFST_MEDIATYPE].Value >>= aType;
    1076         202 :         if ( !aType.isEmpty() )
    1077             :         {
    1078             :             // only nonempty type makes sence here
    1079         202 :             nSeqLength++;
    1080         202 :             ( *aIter )[PKG_MNFST_FULLPATH].Value >>= aPath;
    1081         202 :             aOverridesSequence[nSeqLength-1].First = "/" + aPath;
    1082         202 :             aOverridesSequence[nSeqLength-1].Second = aType;
    1083             :         }
    1084         202 :     }
    1085          25 :     aOverridesSequence.realloc( nSeqLength );
    1086             : 
    1087             :     ::comphelper::OFOPXMLHelper::WriteContentSequence(
    1088          25 :             xConTypeOutStream, aDefaultsSequence, aOverridesSequence, comphelper::getComponentContext(m_xFactory) );
    1089             : 
    1090          25 :     sal_Int32 nBufferLength = static_cast < sal_Int32 > ( pBuffer->getPosition() );
    1091          25 :     pBuffer->realloc( nBufferLength );
    1092             : 
    1093             :     // there is no encryption in this format currently
    1094          25 :     aZipOut.putNextEntry( *pEntry, NULL );
    1095          25 :     aZipOut.write( pBuffer->getSequence(), 0, nBufferLength );
    1096          25 :     aZipOut.closeEntry();
    1097          25 : }
    1098             : 
    1099             : //--------------------------------------------------------
    1100          33 : void ZipPackage::ConnectTo( const uno::Reference< io::XInputStream >& xInStream )
    1101             : {
    1102          33 :     m_xContentSeek.set( xInStream, uno::UNO_QUERY_THROW );
    1103          33 :     m_xContentStream = xInStream;
    1104             : 
    1105             :     // seek back to the beginning of the temp file so we can read segments from it
    1106          33 :     m_xContentSeek->seek( 0 );
    1107          33 :     if ( m_pZipFile )
    1108           0 :         m_pZipFile->setInputStream( m_xContentStream );
    1109             :     else
    1110          33 :         m_pZipFile = new ZipFile ( m_xContentStream, comphelper::getComponentContext(m_xFactory), sal_False );
    1111          33 : }
    1112             : 
    1113             : //--------------------------------------------------------
    1114          33 : uno::Reference< io::XInputStream > ZipPackage::writeTempFile()
    1115             : {
    1116             :     // In case the target local file does not exist or empty
    1117             :     // write directly to it otherwize create a temporary file to write to.
    1118             :     // If a temporary file is created it is returned back by the method.
    1119             :     // If the data written directly, xComponentStream will be switched here
    1120             : 
    1121          33 :     sal_Bool bUseTemp = sal_True;
    1122          33 :     uno::Reference < io::XInputStream > xResult;
    1123          33 :     uno::Reference < io::XInputStream > xTempIn;
    1124             : 
    1125          33 :     uno::Reference < io::XOutputStream > xTempOut;
    1126          33 :     uno::Reference< io::XActiveDataStreamer > xSink;
    1127             : 
    1128          33 :     if ( m_eMode == e_IMode_URL && !m_pZipFile && isLocalFile() )
    1129             :     {
    1130           0 :         xSink = openOriginalForOutput();
    1131           0 :         if( xSink.is() )
    1132             :         {
    1133           0 :             uno::Reference< io::XStream > xStr = xSink->getStream();
    1134           0 :             if( xStr.is() )
    1135             :             {
    1136           0 :                 xTempOut = xStr->getOutputStream();
    1137           0 :                 if( xTempOut.is() )
    1138           0 :                     bUseTemp = sal_False;
    1139           0 :             }
    1140             :         }
    1141             :     }
    1142          33 :     else if ( m_eMode == e_IMode_XStream && !m_pZipFile )
    1143             :     {
    1144             :         // write directly to an empty stream
    1145          33 :         xTempOut = m_xStream->getOutputStream();
    1146          33 :         if( xTempOut.is() )
    1147          33 :             bUseTemp = sal_False;
    1148             :     }
    1149             : 
    1150          33 :     if( bUseTemp )
    1151             :     {
    1152             :         // create temporary file
    1153           0 :         uno::Reference < io::XStream > xTempFile( io::TempFile::create(comphelper::getComponentContext(m_xFactory)), UNO_QUERY_THROW );
    1154           0 :         xTempOut.set( xTempFile->getOutputStream(), UNO_SET_THROW );
    1155           0 :         xTempIn.set( xTempFile->getInputStream(), UNO_SET_THROW );
    1156             :     }
    1157             : 
    1158             :     // Hand it to the ZipOutputStream:
    1159          33 :     ZipOutputStream aZipOut( comphelper::getComponentContext(m_xFactory), xTempOut );
    1160          33 :     aZipOut.setMethod( DEFLATED );
    1161          33 :     aZipOut.setLevel( DEFAULT_COMPRESSION );
    1162             : 
    1163             :     try
    1164             :     {
    1165          33 :         if ( m_nFormat == embed::StorageFormats::PACKAGE )
    1166             :         {
    1167             :             // Remove the old manifest.xml file as the
    1168             :             // manifest will be re-generated and the
    1169             :             // META-INF directory implicitly created if does not exist
    1170           8 :             const OUString sMeta ("META-INF");
    1171             : 
    1172           8 :             if ( m_xRootFolder->hasByName( sMeta ) )
    1173             :             {
    1174           0 :                 const OUString sManifest ("manifest.xml");
    1175             : 
    1176           0 :                 uno::Reference< XUnoTunnel > xTunnel;
    1177           0 :                 Any aAny = m_xRootFolder->getByName( sMeta );
    1178           0 :                 aAny >>= xTunnel;
    1179           0 :                 uno::Reference< XNameContainer > xMetaInfFolder( xTunnel, UNO_QUERY );
    1180           0 :                 if ( xMetaInfFolder.is() && xMetaInfFolder->hasByName( sManifest ) )
    1181           0 :                     xMetaInfFolder->removeByName( sManifest );
    1182             :             }
    1183             : 
    1184             :             // Write a magic file with mimetype
    1185           8 :             WriteMimetypeMagicFile( aZipOut );
    1186             :         }
    1187          25 :         else if ( m_nFormat == embed::StorageFormats::OFOPXML )
    1188             :         {
    1189             :             // Remove the old [Content_Types].xml file as the
    1190             :             // file will be re-generated
    1191             : 
    1192          25 :             const OUString aContentTypes("[Content_Types].xml");
    1193             : 
    1194          25 :             if ( m_xRootFolder->hasByName( aContentTypes ) )
    1195           0 :                 m_xRootFolder->removeByName( aContentTypes );
    1196             :         }
    1197             : 
    1198             :         // Create a vector to store data for the manifest.xml file
    1199          33 :         vector < uno::Sequence < PropertyValue > > aManList;
    1200             : 
    1201          33 :         const OUString sMediaType ("MediaType");
    1202          33 :         const OUString sVersion ("Version");
    1203          33 :         const OUString sFullPath ("FullPath");
    1204             : 
    1205          33 :         if ( m_nFormat == embed::StorageFormats::PACKAGE )
    1206             :         {
    1207           8 :             uno::Sequence < PropertyValue > aPropSeq( PKG_SIZE_NOENCR_MNFST );
    1208           8 :             aPropSeq [PKG_MNFST_MEDIATYPE].Name = sMediaType;
    1209           8 :             aPropSeq [PKG_MNFST_MEDIATYPE].Value <<= m_pRootFolder->GetMediaType();
    1210           8 :             aPropSeq [PKG_MNFST_VERSION].Name = sVersion;
    1211           8 :             aPropSeq [PKG_MNFST_VERSION].Value <<= m_pRootFolder->GetVersion();
    1212           8 :             aPropSeq [PKG_MNFST_FULLPATH].Name = sFullPath;
    1213           8 :             aPropSeq [PKG_MNFST_FULLPATH].Value <<= OUString("/");
    1214             : 
    1215           8 :             aManList.push_back( aPropSeq );
    1216             :         }
    1217             : 
    1218             :         // Get a random number generator and seed it with current timestamp
    1219             :         // This will be used to generate random salt and initialisation vectors
    1220             :         // for encrypted streams
    1221             :         TimeValue aTime;
    1222          33 :         osl_getSystemTime( &aTime );
    1223          33 :         rtlRandomPool aRandomPool = rtl_random_createPool ();
    1224          33 :         rtl_random_addBytes ( aRandomPool, &aTime, 8 );
    1225             : 
    1226             :         // call saveContents ( it will recursively save sub-directories
    1227          33 :         OUString aEmptyString;
    1228          33 :         m_pRootFolder->saveContents( aEmptyString, aManList, aZipOut, GetEncryptionKey(), aRandomPool );
    1229             : 
    1230             :         // Clean up random pool memory
    1231          33 :         rtl_random_destroyPool ( aRandomPool );
    1232             : 
    1233          33 :         if( m_nFormat == embed::StorageFormats::PACKAGE )
    1234             :         {
    1235           8 :             WriteManifest( aZipOut, aManList );
    1236             :         }
    1237          25 :         else if( m_nFormat == embed::StorageFormats::OFOPXML )
    1238             :         {
    1239          25 :             WriteContentTypes( aZipOut, aManList );
    1240             :         }
    1241             : 
    1242          33 :         aZipOut.finish();
    1243             : 
    1244          33 :         if( bUseTemp )
    1245           0 :             xResult = xTempIn;
    1246             : 
    1247             :         // Update our References to point to the new temp file
    1248          33 :         if( !bUseTemp )
    1249             :         {
    1250             :             // the case when the original contents were written directly
    1251          33 :             xTempOut->flush();
    1252             : 
    1253             :             // in case the stream is based on a file it will implement the following interface
    1254             :             // the call should be used to be sure that the contents are written to the file system
    1255          33 :             uno::Reference< io::XAsyncOutputMonitor > asyncOutputMonitor( xTempOut, uno::UNO_QUERY );
    1256          33 :             if ( asyncOutputMonitor.is() )
    1257          33 :                 asyncOutputMonitor->waitForCompletion();
    1258             : 
    1259             :             // no need to postpone switching to the new stream since the target was written directly
    1260          33 :             uno::Reference< io::XInputStream > xNewStream;
    1261          33 :             if ( m_eMode == e_IMode_URL )
    1262           0 :                 xNewStream = xSink->getStream()->getInputStream();
    1263          33 :             else if ( m_eMode == e_IMode_XStream && m_xStream.is() )
    1264          33 :                 xNewStream = m_xStream->getInputStream();
    1265             : 
    1266          33 :             if ( xNewStream.is() )
    1267          33 :                 ConnectTo( xNewStream );
    1268          33 :         }
    1269             :     }
    1270           0 :     catch ( uno::Exception& )
    1271             :     {
    1272           0 :         if( bUseTemp )
    1273             :         {
    1274             :             // no information loss appeares, thus no special handling is required
    1275           0 :                uno::Any aCaught( ::cppu::getCaughtException() );
    1276             : 
    1277             :             // it is allowed to throw WrappedTargetException
    1278           0 :             WrappedTargetException aException;
    1279           0 :             if ( aCaught >>= aException )
    1280           0 :                 throw aException;
    1281             : 
    1282             :             throw WrappedTargetException(
    1283             :                     OSL_LOG_PREFIX "Problem writing the original content!",
    1284             :                     static_cast < OWeakObject * > ( this ),
    1285           0 :                     aCaught );
    1286             :         }
    1287             :         else
    1288             :         {
    1289             :             // the document is written directly, although it was empty it is important to notify that the writing has failed
    1290             :             // TODO/LATER: let the package be able to recover in this situation
    1291           0 :             OUString aErrTxt(OSL_LOG_PREFIX "This package is unusable!");
    1292           0 :             embed::UseBackupException aException( aErrTxt, uno::Reference< uno::XInterface >(), OUString() );
    1293             :             throw WrappedTargetException( aErrTxt,
    1294             :                                             static_cast < OWeakObject * > ( this ),
    1295           0 :                                             makeAny ( aException ) );
    1296             :         }
    1297             :     }
    1298             : 
    1299          33 :     return xResult;
    1300             : }
    1301             : 
    1302             : //--------------------------------------------------------
    1303           0 : uno::Reference< XActiveDataStreamer > ZipPackage::openOriginalForOutput()
    1304             : {
    1305             :     // open and truncate the original file
    1306             :     Content aOriginalContent(
    1307             :         m_aURL, uno::Reference< XCommandEnvironment >(),
    1308           0 :         comphelper::getComponentContext( m_xFactory ) );
    1309           0 :     uno::Reference< XActiveDataStreamer > xSink = new ActiveDataStreamer;
    1310             : 
    1311           0 :     if ( m_eMode == e_IMode_URL )
    1312             :     {
    1313             :         try
    1314             :         {
    1315           0 :             sal_Bool bTruncSuccess = sal_False;
    1316             : 
    1317             :             try
    1318             :             {
    1319           0 :                 Exception aDetect;
    1320           0 :                 sal_Int64 aSize = 0;
    1321           0 :                 Any aAny = aOriginalContent.setPropertyValue("Size", makeAny( aSize ) );
    1322           0 :                 if( !( aAny >>= aDetect ) )
    1323           0 :                     bTruncSuccess = sal_True;
    1324             :             }
    1325           0 :             catch( Exception& )
    1326             :             {
    1327             :             }
    1328             : 
    1329           0 :             if( !bTruncSuccess )
    1330             :             {
    1331             :                 // the file is not accessible
    1332             :                 // just try to write an empty stream to it
    1333             : 
    1334           0 :                 uno::Reference< XInputStream > xTempIn = new DummyInputStream; //uno::Reference< XInputStream >( xTempOut, UNO_QUERY );
    1335           0 :                 aOriginalContent.writeStream( xTempIn , sal_True );
    1336             :             }
    1337             : 
    1338           0 :             OpenCommandArgument2 aArg;
    1339           0 :                aArg.Mode        = OpenMode::DOCUMENT;
    1340           0 :                aArg.Priority    = 0; // unused
    1341           0 :                aArg.Sink       = xSink;
    1342           0 :                aArg.Properties = uno::Sequence< Property >( 0 ); // unused
    1343             : 
    1344           0 :             aOriginalContent.executeCommand("open", makeAny( aArg ) );
    1345             :         }
    1346           0 :         catch( Exception& )
    1347             :         {
    1348             :             // seems to be nonlocal file
    1349             :             // temporary file mechanics should be used
    1350             :         }
    1351             :     }
    1352             : 
    1353           0 :     return xSink;
    1354             : }
    1355             : 
    1356             : //--------------------------------------------------------
    1357          33 : void SAL_CALL ZipPackage::commitChanges()
    1358             :         throw( WrappedTargetException, RuntimeException )
    1359             : {
    1360             :     // lock the component for the time of commiting
    1361          33 :     ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
    1362             : 
    1363          33 :     if ( m_eMode == e_IMode_XInputStream )
    1364             :     {
    1365           0 :         IOException aException;
    1366             :         throw WrappedTargetException(OSL_LOG_PREFIX "This package is read only!",
    1367           0 :                 static_cast < OWeakObject * > ( this ), makeAny ( aException ) );
    1368             :     }
    1369             : 
    1370             :     RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "{ ZipPackage::commitChanges" );
    1371             : 
    1372             :     // first the writeTempFile is called, if it returns a stream the stream should be written to the target
    1373             :     // if no stream was returned, the file was written directly, nothing should be done
    1374             : 
    1375          33 :     uno::Reference< io::XInputStream > xTempInStream = writeTempFile();
    1376          33 :     if ( xTempInStream.is() )
    1377             :     {
    1378           0 :         uno::Reference< io::XSeekable > xTempSeek( xTempInStream, uno::UNO_QUERY_THROW );
    1379             : 
    1380             :         try
    1381             :         {
    1382           0 :             xTempSeek->seek( 0 );
    1383             :         }
    1384           0 :         catch( const uno::Exception& r )
    1385             :         {
    1386             :             throw WrappedTargetException(OSL_LOG_PREFIX "Temporary file should be seekable!",
    1387           0 :                     static_cast < OWeakObject * > ( this ), makeAny ( r ) );
    1388             :         }
    1389             : 
    1390             :         // connect to the temporary stream
    1391           0 :         ConnectTo( xTempInStream );
    1392             : 
    1393           0 :         if ( m_eMode == e_IMode_XStream )
    1394             :         {
    1395             :             // First truncate our output stream
    1396           0 :             uno::Reference < XOutputStream > xOutputStream;
    1397             : 
    1398             :             // preparation for copy step
    1399             :             try
    1400             :             {
    1401           0 :                 xOutputStream = m_xStream->getOutputStream();
    1402           0 :                 uno::Reference < XTruncate > xTruncate ( xOutputStream, UNO_QUERY );
    1403           0 :                 if ( !xTruncate.is() )
    1404           0 :                     throw uno::RuntimeException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
    1405             : 
    1406             :                 // after successful truncation the original file contents are already lost
    1407           0 :                 xTruncate->truncate();
    1408             :             }
    1409           0 :             catch( const uno::Exception& r )
    1410             :             {
    1411             :                 throw WrappedTargetException(OSL_LOG_PREFIX "This package is read only!",
    1412           0 :                         static_cast < OWeakObject * > ( this ), makeAny ( r ) );
    1413             :             }
    1414             : 
    1415             :             try
    1416             :             {
    1417             :                 // then copy the contents of the tempfile to our output stream
    1418           0 :                 ::comphelper::OStorageHelper::CopyInputToOutput( xTempInStream, xOutputStream );
    1419           0 :                 xOutputStream->flush();
    1420             :                 uno::Reference< io::XAsyncOutputMonitor > asyncOutputMonitor(
    1421           0 :                     xOutputStream, uno::UNO_QUERY );
    1422           0 :                 if ( asyncOutputMonitor.is() ) {
    1423           0 :                     asyncOutputMonitor->waitForCompletion();
    1424           0 :                 }
    1425             :             }
    1426           0 :             catch( uno::Exception& )
    1427             :             {
    1428             :                 // if anything goes wrong in this block the target file becomes corrupted
    1429             :                 // so an exception should be thrown as a notification about it
    1430             :                 // and the package must disconnect from the stream
    1431           0 :                 DisconnectFromTargetAndThrowException_Impl( xTempInStream );
    1432           0 :             }
    1433             :         }
    1434           0 :         else if ( m_eMode == e_IMode_URL )
    1435             :         {
    1436           0 :             uno::Reference< XOutputStream > aOrigFileStream;
    1437           0 :             sal_Bool bCanBeCorrupted = sal_False;
    1438             : 
    1439           0 :             if( isLocalFile() )
    1440             :             {
    1441             :                 // write directly in case of local file
    1442             :                 uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess3 > xSimpleAccess(
    1443           0 :                     SimpleFileAccess::create( comphelper::getComponentContext(m_xFactory) ) );
    1444             :                 OSL_ENSURE( xSimpleAccess.is(), "Can't instatiate SimpleFileAccess service!\n" );
    1445           0 :                 uno::Reference< io::XTruncate > xOrigTruncate;
    1446           0 :                 if ( xSimpleAccess.is() )
    1447             :                 {
    1448             :                     try
    1449             :                     {
    1450           0 :                         aOrigFileStream = xSimpleAccess->openFileWrite( m_aURL );
    1451           0 :                         xOrigTruncate = uno::Reference< io::XTruncate >( aOrigFileStream, uno::UNO_QUERY_THROW );
    1452             :                         // after successful truncation the file is already corrupted
    1453           0 :                         xOrigTruncate->truncate();
    1454             :                     }
    1455           0 :                     catch( uno::Exception& )
    1456             :                     {}
    1457             :                 }
    1458             : 
    1459           0 :                 if( xOrigTruncate.is() )
    1460             :                 {
    1461             :                     try
    1462             :                     {
    1463           0 :                         ::comphelper::OStorageHelper::CopyInputToOutput( xTempInStream, aOrigFileStream );
    1464           0 :                         aOrigFileStream->closeOutput();
    1465             :                     }
    1466           0 :                     catch( uno::Exception& )
    1467             :                     {
    1468             :                         try {
    1469           0 :                             aOrigFileStream->closeOutput();
    1470           0 :                         } catch ( uno::Exception& ) {}
    1471             : 
    1472           0 :                         aOrigFileStream = uno::Reference< XOutputStream >();
    1473             :                         // the original file can already be corrupted
    1474           0 :                         bCanBeCorrupted = sal_True;
    1475             :                     }
    1476           0 :                 }
    1477             :             }
    1478             : 
    1479           0 :             if( !aOrigFileStream.is() )
    1480             :             {
    1481             :                 try
    1482             :                 {
    1483           0 :                     uno::Reference < XPropertySet > xPropSet ( xTempInStream, UNO_QUERY );
    1484             :                     OSL_ENSURE( xPropSet.is(), "This is a temporary file that must implement XPropertySet!\n" );
    1485           0 :                     if ( !xPropSet.is() )
    1486           0 :                         throw uno::RuntimeException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
    1487             : 
    1488           0 :                     OUString sTargetFolder = m_aURL.copy ( 0, m_aURL.lastIndexOf ( static_cast < sal_Unicode > ( '/' ) ) );
    1489             :                     Content aContent(
    1490             :                         sTargetFolder, uno::Reference< XCommandEnvironment >(),
    1491           0 :                         comphelper::getComponentContext( m_xFactory ) );
    1492             : 
    1493           0 :                     OUString sTempURL;
    1494           0 :                     Any aAny = xPropSet->getPropertyValue ("Uri");
    1495           0 :                     aAny >>= sTempURL;
    1496             : 
    1497           0 :                     TransferInfo aInfo;
    1498           0 :                     aInfo.NameClash = NameClash::OVERWRITE;
    1499           0 :                     aInfo.MoveData = sal_False;
    1500           0 :                     aInfo.SourceURL = sTempURL;
    1501           0 :                     aInfo.NewTitle = rtl::Uri::decode ( m_aURL.copy ( 1 + m_aURL.lastIndexOf ( static_cast < sal_Unicode > ( '/' ) ) ),
    1502             :                                                         rtl_UriDecodeWithCharset,
    1503           0 :                                                         RTL_TEXTENCODING_UTF8 );
    1504           0 :                     aAny <<= aInfo;
    1505             : 
    1506             :                     // if the file is still not corrupted, it can become after the next step
    1507           0 :                     aContent.executeCommand ("transfer", aAny );
    1508             :                 }
    1509           0 :                 catch ( const ::com::sun::star::uno::Exception& r )
    1510             :                 {
    1511           0 :                     if ( bCanBeCorrupted )
    1512           0 :                         DisconnectFromTargetAndThrowException_Impl( xTempInStream );
    1513             : 
    1514             :                     throw WrappedTargetException(
    1515             :                                                 OSL_LOG_PREFIX "This package may be read only!",
    1516             :                                                 static_cast < OWeakObject * > ( this ),
    1517           0 :                                                 makeAny ( r ) );
    1518             :                 }
    1519           0 :             }
    1520           0 :         }
    1521             :     }
    1522             : 
    1523             :     // after successful storing it can be set to false
    1524          33 :     m_bMediaTypeFallbackUsed = sal_False;
    1525             : 
    1526          33 :     RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "} ZipPackage::commitChanges" );
    1527          33 : }
    1528             : 
    1529             : //--------------------------------------------------------
    1530           0 : void ZipPackage::DisconnectFromTargetAndThrowException_Impl( const uno::Reference< io::XInputStream >& xTempStream )
    1531             : {
    1532           0 :     m_xStream = uno::Reference< io::XStream >( xTempStream, uno::UNO_QUERY );
    1533           0 :     if ( m_xStream.is() )
    1534           0 :         m_eMode = e_IMode_XStream;
    1535             :     else
    1536           0 :         m_eMode = e_IMode_XInputStream;
    1537             : 
    1538           0 :     OUString aTempURL;
    1539             :     try {
    1540           0 :         uno::Reference< beans::XPropertySet > xTempFile( xTempStream, uno::UNO_QUERY_THROW );
    1541           0 :         uno::Any aUrl = xTempFile->getPropertyValue("Uri");
    1542           0 :         aUrl >>= aTempURL;
    1543           0 :         xTempFile->setPropertyValue("RemoveFile",
    1544           0 :                                      uno::makeAny( sal_False ) );
    1545             :     }
    1546           0 :     catch ( uno::Exception& )
    1547             :     {
    1548             :         OSL_FAIL( "These calls are pretty simple, they should not fail!\n" );
    1549             :     }
    1550             : 
    1551           0 :     OUString aErrTxt(OSL_LOG_PREFIX "This package is read only!");
    1552           0 :     embed::UseBackupException aException( aErrTxt, uno::Reference< uno::XInterface >(), aTempURL );
    1553             :     throw WrappedTargetException( aErrTxt,
    1554             :                                     static_cast < OWeakObject * > ( this ),
    1555           0 :                                     makeAny ( aException ) );
    1556             : }
    1557             : 
    1558             : //--------------------------------------------------------
    1559          45 : const uno::Sequence< sal_Int8 > ZipPackage::GetEncryptionKey()
    1560             : {
    1561          45 :     uno::Sequence< sal_Int8 > aResult;
    1562             : 
    1563          45 :     if ( m_aStorageEncryptionKeys.getLength() )
    1564             :     {
    1565          13 :         OUString aNameToFind;
    1566          13 :         if ( m_nStartKeyGenerationID == xml::crypto::DigestID::SHA256 )
    1567          13 :             aNameToFind = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
    1568           0 :         else if ( m_nStartKeyGenerationID == xml::crypto::DigestID::SHA1 )
    1569           0 :             aNameToFind = PACKAGE_ENCRYPTIONDATA_SHA1UTF8;
    1570             :         else
    1571           0 :             throw uno::RuntimeException(OSL_LOG_PREFIX "No expected key is provided!", uno::Reference< uno::XInterface >() );
    1572             : 
    1573          52 :         for ( sal_Int32 nInd = 0; nInd < m_aStorageEncryptionKeys.getLength(); nInd++ )
    1574          39 :             if ( m_aStorageEncryptionKeys[nInd].Name.equals( aNameToFind ) )
    1575          13 :                 m_aStorageEncryptionKeys[nInd].Value >>= aResult;
    1576             : 
    1577             :         // empty keys are not allowed here
    1578             :         // so it is not important whether there is no key, or the key is empty, it is an error
    1579          13 :         if ( !aResult.getLength() )
    1580           0 :             throw uno::RuntimeException(OSL_LOG_PREFIX "No expected key is provided!", uno::Reference< uno::XInterface >() );
    1581             :     }
    1582             :     else
    1583          32 :         aResult = m_aEncryptionKey;
    1584             : 
    1585          45 :     return aResult;
    1586             : }
    1587             : 
    1588             : //--------------------------------------------------------
    1589           0 : sal_Bool SAL_CALL ZipPackage::hasPendingChanges()
    1590             :         throw( RuntimeException )
    1591             : {
    1592           0 :     return sal_False;
    1593             : }
    1594             : //--------------------------------------------------------
    1595           0 : Sequence< ElementChange > SAL_CALL ZipPackage::getPendingChanges()
    1596             :         throw( RuntimeException )
    1597             : {
    1598           0 :     return uno::Sequence < ElementChange > ();
    1599             : }
    1600             : 
    1601             : /**
    1602             :  * Function to create a new component instance; is needed by factory helper implementation.
    1603             :  * @param xMgr service manager to if the components needs other component instances
    1604             :  */
    1605        1016 : uno::Reference < XInterface >SAL_CALL ZipPackage_createInstance(
    1606             :     const uno::Reference< XMultiServiceFactory > & xMgr )
    1607             : {
    1608        1016 :     return uno::Reference< XInterface >( *new ZipPackage( xMgr ) );
    1609             : }
    1610             : 
    1611             : //--------------------------------------------------------
    1612          41 : OUString ZipPackage::static_getImplementationName()
    1613             : {
    1614          41 :     return OUString("com.sun.star.packages.comp.ZipPackage");
    1615             : }
    1616             : 
    1617             : //--------------------------------------------------------
    1618          15 : Sequence< OUString > ZipPackage::static_getSupportedServiceNames()
    1619             : {
    1620          15 :     uno::Sequence< OUString > aNames( 1 );
    1621          15 :     aNames[0] = OUString("com.sun.star.packages.Package");
    1622          15 :     return aNames;
    1623             : }
    1624             : //--------------------------------------------------------
    1625           0 : sal_Bool SAL_CALL ZipPackage::static_supportsService( OUString const & rServiceName )
    1626             : {
    1627           0 :     return rServiceName == getSupportedServiceNames()[0];
    1628             : }
    1629             : 
    1630             : //--------------------------------------------------------
    1631           0 : OUString ZipPackage::getImplementationName()
    1632             :     throw ( RuntimeException )
    1633             : {
    1634           0 :     return static_getImplementationName();
    1635             : }
    1636             : 
    1637             : //--------------------------------------------------------
    1638           0 : Sequence< OUString > ZipPackage::getSupportedServiceNames()
    1639             :     throw ( RuntimeException )
    1640             : {
    1641           0 :     return static_getSupportedServiceNames();
    1642             : }
    1643             : //--------------------------------------------------------
    1644           0 : sal_Bool SAL_CALL ZipPackage::supportsService( OUString const & rServiceName )
    1645             :     throw ( RuntimeException )
    1646             : {
    1647           0 :     return static_supportsService ( rServiceName );
    1648             : }
    1649             : //--------------------------------------------------------
    1650          15 : uno::Reference < XSingleServiceFactory > ZipPackage::createServiceFactory( uno::Reference < XMultiServiceFactory > const & rServiceFactory )
    1651             : {
    1652             :     return cppu::createSingleFactory ( rServiceFactory,
    1653             :                                            static_getImplementationName(),
    1654             :                                            ZipPackage_createInstance,
    1655          15 :                                            static_getSupportedServiceNames() );
    1656             : }
    1657             : 
    1658             : namespace { struct lcl_ImplId : public rtl::Static< ::cppu::OImplementationId, lcl_ImplId > {}; }
    1659             : 
    1660             : //--------------------------------------------------------
    1661           0 : Sequence< sal_Int8 > ZipPackage::getUnoTunnelImplementationId( void )
    1662             :     throw ( RuntimeException )
    1663             : {
    1664           0 :     ::cppu::OImplementationId &rId = lcl_ImplId::get();
    1665           0 :     return rId.getImplementationId();
    1666             : }
    1667             : 
    1668             : //--------------------------------------------------------
    1669           0 : sal_Int64 SAL_CALL ZipPackage::getSomething( const uno::Sequence< sal_Int8 >& aIdentifier )
    1670             :     throw( RuntimeException )
    1671             : {
    1672           0 :     if ( aIdentifier.getLength() == 16 && 0 == memcmp( getUnoTunnelImplementationId().getConstArray(),  aIdentifier.getConstArray(), 16 ) )
    1673           0 :         return reinterpret_cast < sal_Int64 > ( this );
    1674           0 :     return 0;
    1675             : }
    1676             : 
    1677             : //--------------------------------------------------------
    1678           0 : uno::Reference< XPropertySetInfo > SAL_CALL ZipPackage::getPropertySetInfo()
    1679             :         throw( RuntimeException )
    1680             : {
    1681           0 :     return uno::Reference < XPropertySetInfo > ();
    1682             : }
    1683             : 
    1684             : //--------------------------------------------------------
    1685         436 : void SAL_CALL ZipPackage::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
    1686             :         throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
    1687             : {
    1688         436 :     if ( m_nFormat != embed::StorageFormats::PACKAGE )
    1689           0 :         throw UnknownPropertyException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
    1690             : 
    1691        1744 :     if (aPropertyName == HAS_ENCRYPTED_ENTRIES_PROPERTY
    1692         436 :       ||aPropertyName == HAS_NONENCRYPTED_ENTRIES_PROPERTY
    1693         436 :       ||aPropertyName == IS_INCONSISTENT_PROPERTY
    1694         436 :       ||aPropertyName == MEDIATYPE_FALLBACK_USED_PROPERTY)
    1695           0 :         throw PropertyVetoException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
    1696         436 :     else if ( aPropertyName == ENCRYPTION_KEY_PROPERTY )
    1697             :     {
    1698           0 :         if ( !( aValue >>= m_aEncryptionKey ) )
    1699           0 :             throw IllegalArgumentException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 2 );
    1700             : 
    1701           0 :         m_aStorageEncryptionKeys.realloc( 0 );
    1702             :     }
    1703         436 :     else if ( aPropertyName == STORAGE_ENCRYPTION_KEYS_PROPERTY )
    1704             :     {
    1705             :         // this property is only necessary to support raw passwords in storage API;
    1706             :         // because of this support the storage has to operate with more than one key dependent on storage generation algorithm;
    1707             :         // when this support is removed, the storage will get only one key from outside
    1708             :         // TODO/LATER: Get rid of this property as well as of support of raw passwords in storages
    1709          10 :         uno::Sequence< beans::NamedValue > aKeys;
    1710          10 :         if ( !( aValue >>= aKeys ) || ( aKeys.getLength() && aKeys.getLength() < 2 ) )
    1711           0 :             throw IllegalArgumentException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 2 );
    1712             : 
    1713          10 :         if ( aKeys.getLength() )
    1714             :         {
    1715          10 :             bool bHasSHA256 = false;
    1716          10 :             bool bHasSHA1 = false;
    1717          40 :             for ( sal_Int32 nInd = 0; nInd < aKeys.getLength(); nInd++ )
    1718             :             {
    1719          30 :                 if ( aKeys[nInd].Name.equals( PACKAGE_ENCRYPTIONDATA_SHA256UTF8 ) )
    1720          10 :                     bHasSHA256 = true;
    1721          30 :                 if ( aKeys[nInd].Name.equals( PACKAGE_ENCRYPTIONDATA_SHA1UTF8 ) )
    1722          10 :                     bHasSHA1 = true;
    1723             :             }
    1724             : 
    1725          10 :             if ( !bHasSHA256 || !bHasSHA1 )
    1726           0 :                 throw IllegalArgumentException(OSL_LOG_PREFIX "Expected keys are not provided!", uno::Reference< uno::XInterface >(), 2 );
    1727             :         }
    1728             : 
    1729          10 :         m_aStorageEncryptionKeys = aKeys;
    1730          10 :         m_aEncryptionKey.realloc( 0 );
    1731             :     }
    1732         426 :     else if ( aPropertyName == ENCRYPTION_ALGORITHMS_PROPERTY )
    1733             :     {
    1734         426 :         uno::Sequence< beans::NamedValue > aAlgorithms;
    1735         426 :         if ( m_pZipFile || !( aValue >>= aAlgorithms ) || aAlgorithms.getLength() == 0 )
    1736             :         {
    1737             :             // the algorithms can not be changed if the file has a persistence based on the algorithms ( m_pZipFile )
    1738           0 :             throw IllegalArgumentException(OSL_LOG_PREFIX "unexpected algorithms list is provided.", uno::Reference< uno::XInterface >(), 2 );
    1739             :         }
    1740             : 
    1741        1704 :         for ( sal_Int32 nInd = 0; nInd < aAlgorithms.getLength(); nInd++ )
    1742             :         {
    1743        1278 :             if ( aAlgorithms[nInd].Name == "StartKeyGenerationAlgorithm" )
    1744             :             {
    1745         426 :                 sal_Int32 nID = 0;
    1746         426 :                 if ( !( aAlgorithms[nInd].Value >>= nID )
    1747             :                   || ( nID != xml::crypto::DigestID::SHA256 && nID != xml::crypto::DigestID::SHA1 ) )
    1748           0 :                     throw IllegalArgumentException(OSL_LOG_PREFIX "Unexpected start key generation algorithm is provided!", uno::Reference< uno::XInterface >(), 2 );
    1749             : 
    1750         426 :                 m_nStartKeyGenerationID = nID;
    1751             :             }
    1752         852 :             else if ( aAlgorithms[nInd].Name == "EncryptionAlgorithm" )
    1753             :             {
    1754         426 :                 sal_Int32 nID = 0;
    1755         426 :                 if ( !( aAlgorithms[nInd].Value >>= nID )
    1756             :                   || ( nID != xml::crypto::CipherID::AES_CBC_W3C_PADDING && nID != xml::crypto::CipherID::BLOWFISH_CFB_8 ) )
    1757           0 :                     throw IllegalArgumentException(OSL_LOG_PREFIX "Unexpected start key generation algorithm is provided!", uno::Reference< uno::XInterface >(), 2 );
    1758             : 
    1759         426 :                 m_nCommonEncryptionID = nID;
    1760             :             }
    1761         426 :             else if ( aAlgorithms[nInd].Name == "ChecksumAlgorithm" )
    1762             :             {
    1763         426 :                 sal_Int32 nID = 0;
    1764         426 :                 if ( !( aAlgorithms[nInd].Value >>= nID )
    1765             :                   || ( nID != xml::crypto::DigestID::SHA1_1K && nID != xml::crypto::DigestID::SHA256_1K ) )
    1766           0 :                     throw IllegalArgumentException(OSL_LOG_PREFIX "Unexpected start key generation algorithm is provided!", uno::Reference< uno::XInterface >(), 2 );
    1767             : 
    1768         426 :                 m_nChecksumDigestID = nID;
    1769             :             }
    1770             :             else
    1771             :             {
    1772             :                 OSL_ENSURE( sal_False, "Unexpected encryption algorithm is provided!" );
    1773           0 :                 throw IllegalArgumentException(OSL_LOG_PREFIX "unexpected algorithms list is provided.", uno::Reference< uno::XInterface >(), 2 );
    1774             :             }
    1775         426 :         }
    1776             :     }
    1777             :     else
    1778           0 :         throw UnknownPropertyException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
    1779         436 : }
    1780             : 
    1781             : //--------------------------------------------------------
    1782        5429 : Any SAL_CALL ZipPackage::getPropertyValue( const OUString& PropertyName )
    1783             :         throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
    1784             : {
    1785             :     // TODO/LATER: Activate the check when zip-ucp is ready
    1786             :     // if ( m_nFormat != embed::StorageFormats::PACKAGE )
    1787             :     //  throw UnknownPropertyException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
    1788             : 
    1789        5429 :     Any aAny;
    1790        5429 :     if ( PropertyName == ENCRYPTION_KEY_PROPERTY )
    1791             :     {
    1792           0 :         aAny <<= m_aEncryptionKey;
    1793           0 :         return aAny;
    1794             :     }
    1795        5429 :     else if ( PropertyName == ENCRYPTION_ALGORITHMS_PROPERTY )
    1796             :     {
    1797           0 :         ::comphelper::SequenceAsHashMap aAlgorithms;
    1798           0 :         aAlgorithms["StartKeyGenerationAlgorithm"] <<= m_nStartKeyGenerationID;
    1799           0 :         aAlgorithms["EncryptionAlgorithm"] <<= m_nCommonEncryptionID;
    1800           0 :         aAlgorithms["ChecksumAlgorithm"] <<= m_nChecksumDigestID;
    1801           0 :         aAny <<= aAlgorithms.getAsConstNamedValueList();
    1802           0 :         return aAny;
    1803             :     }
    1804        5429 :     if ( PropertyName == STORAGE_ENCRYPTION_KEYS_PROPERTY )
    1805             :     {
    1806           0 :         aAny <<= m_aStorageEncryptionKeys;
    1807           0 :         return aAny;
    1808             :     }
    1809        5429 :     else if ( PropertyName == HAS_ENCRYPTED_ENTRIES_PROPERTY )
    1810             :     {
    1811         600 :         aAny <<= m_bHasEncryptedEntries;
    1812         600 :         return aAny;
    1813             :     }
    1814        4829 :     else if ( PropertyName == HAS_NONENCRYPTED_ENTRIES_PROPERTY )
    1815             :     {
    1816         557 :         aAny <<= m_bHasNonEncryptedEntries;
    1817         557 :         return aAny;
    1818             :     }
    1819        4272 :     else if ( PropertyName == IS_INCONSISTENT_PROPERTY )
    1820             :     {
    1821          43 :         aAny <<= m_bInconsistent;
    1822          43 :         return aAny;
    1823             :     }
    1824        4229 :     else if ( PropertyName == MEDIATYPE_FALLBACK_USED_PROPERTY )
    1825             :     {
    1826        4229 :         aAny <<= m_bMediaTypeFallbackUsed;
    1827        4229 :         return aAny;
    1828             :     }
    1829           0 :     throw UnknownPropertyException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
    1830             : }
    1831             : //--------------------------------------------------------
    1832           0 : void SAL_CALL ZipPackage::addPropertyChangeListener( const OUString& /*aPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
    1833             :         throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
    1834             : {
    1835           0 : }
    1836             : //--------------------------------------------------------
    1837           0 : void SAL_CALL ZipPackage::removePropertyChangeListener( const OUString& /*aPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*aListener*/ )
    1838             :         throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
    1839             : {
    1840           0 : }
    1841             : //--------------------------------------------------------
    1842           0 : void SAL_CALL ZipPackage::addVetoableChangeListener( const OUString& /*PropertyName*/, const uno::Reference< XVetoableChangeListener >& /*aListener*/ )
    1843             :         throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
    1844             : {
    1845           0 : }
    1846             : //--------------------------------------------------------
    1847           0 : void SAL_CALL ZipPackage::removeVetoableChangeListener( const OUString& /*PropertyName*/, const uno::Reference< XVetoableChangeListener >& /*aListener*/ )
    1848             :         throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
    1849             : {
    1850           0 : }
    1851             : 
    1852             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10