LCOV - code coverage report
Current view: top level - libreoffice/package/source/zippackage - ZipPackageStream.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 191 424 45.0 %
Date: 2012-12-27 Functions: 22 31 71.0 %
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 <com/sun/star/packages/zip/ZipConstants.hpp>
      22             : #include <com/sun/star/embed/StorageFormats.hpp>
      23             : #include <com/sun/star/packages/zip/ZipIOException.hpp>
      24             : #include <com/sun/star/io/TempFile.hpp>
      25             : #include <com/sun/star/io/XInputStream.hpp>
      26             : #include <com/sun/star/io/XOutputStream.hpp>
      27             : #include <com/sun/star/io/XStream.hpp>
      28             : #include <com/sun/star/io/XSeekable.hpp>
      29             : #include <com/sun/star/xml/crypto/DigestID.hpp>
      30             : #include <com/sun/star/xml/crypto/CipherID.hpp>
      31             : 
      32             : #include <string.h>
      33             : 
      34             : #include <ZipPackageStream.hxx>
      35             : #include <ZipPackage.hxx>
      36             : #include <ZipFile.hxx>
      37             : #include <EncryptedDataHeader.hxx>
      38             : #include <osl/diagnose.h>
      39             : #include "wrapstreamforshare.hxx"
      40             : 
      41             : #include <comphelper/processfactory.hxx>
      42             : #include <comphelper/seekableinput.hxx>
      43             : #include <comphelper/storagehelper.hxx>
      44             : 
      45             : #include <rtl/instance.hxx>
      46             : 
      47             : #include <PackageConstants.hxx>
      48             : 
      49             : using namespace com::sun::star::packages::zip::ZipConstants;
      50             : using namespace com::sun::star::packages::zip;
      51             : using namespace com::sun::star::uno;
      52             : using namespace com::sun::star::lang;
      53             : using namespace com::sun::star;
      54             : using namespace cppu;
      55             : 
      56             : namespace { struct lcl_CachedImplId : public rtl::Static< Sequence < sal_Int8 >, lcl_CachedImplId > {}; }
      57             : 
      58        7646 : const ::com::sun::star::uno::Sequence < sal_Int8 >& ZipPackageStream::static_getImplementationId()
      59             : {
      60        7646 :     return lcl_CachedImplId::get();
      61             : }
      62             : 
      63        6826 : ZipPackageStream::ZipPackageStream ( ZipPackage & rNewPackage,
      64             :                                     const uno::Reference< XMultiServiceFactory >& xFactory,
      65             :                                     sal_Bool bAllowRemoveOnInsert )
      66             : : m_xFactory( xFactory )
      67             : , rZipPackage( rNewPackage )
      68             : , bToBeCompressed ( sal_True )
      69             : , bToBeEncrypted ( sal_False )
      70             : , bHaveOwnKey ( sal_False )
      71             : , bIsEncrypted ( sal_False )
      72             : , m_nImportedStartKeyAlgorithm( 0 )
      73             : , m_nImportedEncryptionAlgorithm( 0 )
      74             : , m_nImportedChecksumAlgorithm( 0 )
      75             : , m_nImportedDerivedKeySize( 0 )
      76             : , m_nStreamMode( PACKAGE_STREAM_NOTSET )
      77             : , m_nMagicalHackPos( 0 )
      78             : , m_nMagicalHackSize( 0 )
      79             : , m_bHasSeekable( sal_False )
      80             : , m_bCompressedIsSetFromOutside( sal_False )
      81             : , m_bFromManifest( sal_False )
      82        6826 : , m_bUseWinEncoding( false )
      83             : {
      84             :     OSL_ENSURE( m_xFactory.is(), "No factory is provided to ZipPackageStream!\n" );
      85             : 
      86        6826 :     this->mbAllowRemoveOnInsert = bAllowRemoveOnInsert;
      87             : 
      88        6826 :     SetFolder ( sal_False );
      89        6826 :     aEntry.nVersion     = -1;
      90        6826 :     aEntry.nFlag        = 0;
      91        6826 :     aEntry.nMethod      = -1;
      92        6826 :     aEntry.nTime        = -1;
      93        6826 :     aEntry.nCrc         = -1;
      94        6826 :     aEntry.nCompressedSize  = -1;
      95        6826 :     aEntry.nSize        = -1;
      96        6826 :     aEntry.nOffset      = -1;
      97        6826 :     aEntry.nPathLen     = -1;
      98        6826 :     aEntry.nExtraLen    = -1;
      99             : 
     100        6826 :     Sequence < sal_Int8 > &rCachedImplId = lcl_CachedImplId::get();
     101        6826 :     if ( !rCachedImplId.getLength() )
     102          14 :         rCachedImplId = getImplementationId();
     103        6826 : }
     104             : 
     105       12798 : ZipPackageStream::~ZipPackageStream( void )
     106             : {
     107       12798 : }
     108             : 
     109        4859 : void ZipPackageStream::setZipEntryOnLoading( const ZipEntry &rInEntry )
     110             : {
     111        4859 :     aEntry.nVersion = rInEntry.nVersion;
     112        4859 :     aEntry.nFlag = rInEntry.nFlag;
     113        4859 :     aEntry.nMethod = rInEntry.nMethod;
     114        4859 :     aEntry.nTime = rInEntry.nTime;
     115        4859 :     aEntry.nCrc = rInEntry.nCrc;
     116        4859 :     aEntry.nCompressedSize = rInEntry.nCompressedSize;
     117        4859 :     aEntry.nSize = rInEntry.nSize;
     118        4859 :     aEntry.nOffset = rInEntry.nOffset;
     119        4859 :     aEntry.sPath = rInEntry.sPath;
     120        4859 :     aEntry.nPathLen = rInEntry.nPathLen;
     121        4859 :     aEntry.nExtraLen = rInEntry.nExtraLen;
     122             : 
     123        4859 :     if ( aEntry.nMethod == STORED )
     124         305 :         bToBeCompressed = sal_False;
     125        4859 : }
     126             : 
     127             : //--------------------------------------------------------------------------
     128         235 : void ZipPackageStream::CloseOwnStreamIfAny()
     129             : {
     130         235 :     if ( xStream.is() )
     131             :     {
     132         235 :         xStream->closeInput();
     133         235 :         xStream = uno::Reference< io::XInputStream >();
     134         235 :         m_bHasSeekable = sal_False;
     135             :     }
     136         235 : }
     137             : 
     138             : //--------------------------------------------------------------------------
     139         520 : uno::Reference< io::XInputStream > ZipPackageStream::GetOwnSeekStream()
     140             : {
     141         520 :     if ( !m_bHasSeekable && xStream.is() )
     142             :     {
     143             :         // The package component requires that every stream either be FROM a package or it must support XSeekable!
     144             :         // The only exception is a nonseekable stream that is provided only for storing, if such a stream
     145             :         // is accessed before commit it MUST be wrapped.
     146             :         // Wrap the stream in case it is not seekable
     147         260 :         xStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( xStream, comphelper::getComponentContext( m_xFactory ) );
     148         260 :         uno::Reference< io::XSeekable > xSeek( xStream, UNO_QUERY );
     149         260 :         if ( !xSeek.is() )
     150             :             throw RuntimeException( OSL_LOG_PREFIX "The stream must support XSeekable!",
     151           0 :                                     uno::Reference< XInterface >() );
     152             : 
     153         260 :         m_bHasSeekable = sal_True;
     154             :     }
     155             : 
     156         520 :     return xStream;
     157             : }
     158             : 
     159             : //--------------------------------------------------------------------------
     160           0 : uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCopy()
     161             : {
     162           0 :     if ( m_nStreamMode != PACKAGE_STREAM_RAW || !GetOwnSeekStream().is() )
     163           0 :         throw io::IOException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     164             : 
     165           0 :     if ( m_xBaseEncryptionData.is() )
     166             :         throw ZipIOException(OSL_LOG_PREFIX "Encrypted stream without encryption data!\n",
     167           0 :                             uno::Reference< XInterface >() );
     168             : 
     169           0 :     uno::Reference< io::XSeekable > xSeek( GetOwnSeekStream(), UNO_QUERY );
     170           0 :     if ( !xSeek.is() )
     171             :         throw ZipIOException(OSL_LOG_PREFIX "The stream must be seekable!\n",
     172           0 :                             uno::Reference< XInterface >() );
     173             : 
     174             :     // skip header
     175           0 :     xSeek->seek( n_ConstHeaderSize + getInitialisationVector().getLength() +
     176           0 :                     getSalt().getLength() + getDigest().getLength() );
     177             : 
     178             :     // create temporary stream
     179             :     uno::Reference < io::XOutputStream > xTempOut(
     180             :                         io::TempFile::create(comphelper::getComponentContext(m_xFactory)),
     181           0 :                         uno::UNO_QUERY_THROW );
     182           0 :     uno::Reference < io::XInputStream > xTempIn( xTempOut, UNO_QUERY_THROW );
     183           0 :     uno::Reference < io::XSeekable > xTempSeek( xTempOut, UNO_QUERY_THROW );
     184             : 
     185             :     // copy the raw stream to the temporary file starting from the current position
     186           0 :     ::comphelper::OStorageHelper::CopyInputToOutput( GetOwnSeekStream(), xTempOut );
     187           0 :     xTempOut->closeOutput();
     188           0 :     xTempSeek->seek( 0 );
     189             : 
     190           0 :     return xTempIn;
     191             : }
     192             : 
     193             : //--------------------------------------------------------------------------
     194          28 : sal_Int32 ZipPackageStream::GetEncryptionAlgorithm() const
     195             : {
     196          28 :     return m_nImportedEncryptionAlgorithm ? m_nImportedEncryptionAlgorithm : rZipPackage.GetEncAlgID();
     197             : }
     198             : 
     199             : //--------------------------------------------------------------------------
     200           4 : sal_Int32 ZipPackageStream::GetBlockSize() const
     201             : {
     202           4 :     return GetEncryptionAlgorithm() == ::com::sun::star::xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 16 : 8;
     203             : }
     204             : 
     205             : //--------------------------------------------------------------------------
     206        2308 : ::rtl::Reference< EncryptionData > ZipPackageStream::GetEncryptionData( bool bUseWinEncoding )
     207             : {
     208        2308 :     ::rtl::Reference< EncryptionData > xResult;
     209        2308 :     if ( m_xBaseEncryptionData.is() )
     210             :         xResult = new EncryptionData(
     211          24 :             *m_xBaseEncryptionData,
     212             :             GetEncryptionKey( bUseWinEncoding ),
     213             :             GetEncryptionAlgorithm(),
     214          12 :             m_nImportedChecksumAlgorithm ? m_nImportedChecksumAlgorithm : rZipPackage.GetChecksumAlgID(),
     215          12 :             m_nImportedDerivedKeySize ? m_nImportedDerivedKeySize : rZipPackage.GetDefaultDerivedKeySize(),
     216          48 :             GetStartKeyGenID() );
     217             : 
     218        2308 :     return xResult;
     219             : }
     220             : 
     221             : //--------------------------------------------------------------------------
     222          24 : uno::Sequence< sal_Int8 > ZipPackageStream::GetEncryptionKey( bool bUseWinEncoding )
     223             : {
     224          24 :     uno::Sequence< sal_Int8 > aResult;
     225          24 :     sal_Int32 nKeyGenID = GetStartKeyGenID();
     226          24 :     bUseWinEncoding = ( bUseWinEncoding || m_bUseWinEncoding );
     227             : 
     228          24 :     if ( bHaveOwnKey && m_aStorageEncryptionKeys.getLength() )
     229             :     {
     230          12 :         OUString aNameToFind;
     231          12 :         if ( nKeyGenID == xml::crypto::DigestID::SHA256 )
     232           8 :             aNameToFind = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
     233           4 :         else if ( nKeyGenID == xml::crypto::DigestID::SHA1 )
     234             :         {
     235           4 :             aNameToFind = bUseWinEncoding ? PACKAGE_ENCRYPTIONDATA_SHA1MS1252 : PACKAGE_ENCRYPTIONDATA_SHA1UTF8;
     236             :         }
     237             :         else
     238           0 :             throw uno::RuntimeException(OSL_LOG_PREFIX "No expected key is provided!", uno::Reference< uno::XInterface >() );
     239             : 
     240          48 :         for ( sal_Int32 nInd = 0; nInd < m_aStorageEncryptionKeys.getLength(); nInd++ )
     241          36 :             if ( m_aStorageEncryptionKeys[nInd].Name.equals( aNameToFind ) )
     242          12 :                 m_aStorageEncryptionKeys[nInd].Value >>= aResult;
     243             : 
     244             :         // empty keys are not allowed here
     245             :         // so it is not important whether there is no key, or the key is empty, it is an error
     246          12 :         if ( !aResult.getLength() )
     247           0 :             throw uno::RuntimeException(OSL_LOG_PREFIX "No expected key is provided!", uno::Reference< uno::XInterface >() );
     248             :     }
     249             :     else
     250          12 :         aResult = m_aEncryptionKey;
     251             : 
     252          24 :     if ( !aResult.getLength() || !bHaveOwnKey )
     253          12 :         aResult = rZipPackage.GetEncryptionKey();
     254             : 
     255          24 :     return aResult;
     256             : }
     257             : 
     258             : //--------------------------------------------------------------------------
     259          48 : sal_Int32 ZipPackageStream::GetStartKeyGenID()
     260             : {
     261             :     // generally should all the streams use the same Start Key
     262             :     // but if raw copy without password takes place, we should preserve the imported algorithm
     263          48 :     return m_nImportedStartKeyAlgorithm ? m_nImportedStartKeyAlgorithm : rZipPackage.GetStartKeyGenID();
     264             : }
     265             : 
     266             : //--------------------------------------------------------------------------
     267           0 : uno::Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_Bool bAddHeaderForEncr )
     268             : {
     269           0 :     if ( m_nStreamMode != PACKAGE_STREAM_DATA || !GetOwnSeekStream().is() || ( bAddHeaderForEncr && !bToBeEncrypted ) )
     270           0 :         throw packages::NoEncryptionException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     271             : 
     272           0 :     Sequence< sal_Int8 > aKey;
     273             : 
     274           0 :     if ( bToBeEncrypted )
     275             :     {
     276           0 :         aKey = GetEncryptionKey();
     277           0 :         if ( !aKey.getLength() )
     278           0 :             throw packages::NoEncryptionException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     279             :     }
     280             : 
     281             :     try
     282             :     {
     283             :         // create temporary file
     284             :         uno::Reference < io::XStream > xTempStream(
     285             :                             io::TempFile::create(comphelper::getComponentContext(m_xFactory)),
     286           0 :                             uno::UNO_QUERY_THROW );
     287             : 
     288             :         // create a package based on it
     289           0 :         ZipPackage* pPackage = new ZipPackage( m_xFactory );
     290           0 :         uno::Reference< XSingleServiceFactory > xPackageAsFactory( static_cast< XSingleServiceFactory* >( pPackage ) );
     291           0 :         if ( !xPackageAsFactory.is() )
     292           0 :             throw RuntimeException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     293             : 
     294           0 :         Sequence< Any > aArgs( 1 );
     295           0 :         aArgs[0] <<= xTempStream;
     296           0 :         pPackage->initialize( aArgs );
     297             : 
     298             :         // create a new package stream
     299           0 :         uno::Reference< XDataSinkEncrSupport > xNewPackStream( xPackageAsFactory->createInstance(), UNO_QUERY );
     300           0 :         if ( !xNewPackStream.is() )
     301           0 :             throw RuntimeException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     302             : 
     303           0 :         xNewPackStream->setDataStream( static_cast< io::XInputStream* >(
     304           0 :                                                     new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ) ) );
     305             : 
     306           0 :         uno::Reference< XPropertySet > xNewPSProps( xNewPackStream, UNO_QUERY );
     307           0 :         if ( !xNewPSProps.is() )
     308           0 :             throw RuntimeException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     309             : 
     310             :         // copy all the properties of this stream to the new stream
     311           0 :         xNewPSProps->setPropertyValue("MediaType", makeAny( sMediaType ) );
     312           0 :         xNewPSProps->setPropertyValue("Compressed", makeAny( bToBeCompressed ) );
     313           0 :         if ( bToBeEncrypted )
     314             :         {
     315           0 :             xNewPSProps->setPropertyValue(ENCRYPTION_KEY_PROPERTY, makeAny( aKey ) );
     316           0 :             xNewPSProps->setPropertyValue("Encrypted", makeAny( sal_True ) );
     317             :         }
     318             : 
     319             :         // insert a new stream in the package
     320           0 :         uno::Reference< XUnoTunnel > xTunnel;
     321           0 :         Any aRoot = pPackage->getByHierarchicalName("/");
     322           0 :         aRoot >>= xTunnel;
     323           0 :         uno::Reference< container::XNameContainer > xRootNameContainer( xTunnel, UNO_QUERY );
     324           0 :         if ( !xRootNameContainer.is() )
     325           0 :             throw RuntimeException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     326             : 
     327           0 :         uno::Reference< XUnoTunnel > xNPSTunnel( xNewPackStream, UNO_QUERY );
     328           0 :         xRootNameContainer->insertByName("dummy", makeAny( xNPSTunnel ) );
     329             : 
     330             :         // commit the temporary package
     331           0 :         pPackage->commitChanges();
     332             : 
     333             :         // get raw stream from the temporary package
     334           0 :         uno::Reference< io::XInputStream > xInRaw;
     335           0 :         if ( bAddHeaderForEncr )
     336           0 :             xInRaw = xNewPackStream->getRawStream();
     337             :         else
     338           0 :             xInRaw = xNewPackStream->getPlainRawStream();
     339             : 
     340             :         // create another temporary file
     341             :         uno::Reference < io::XOutputStream > xTempOut(
     342             :                             io::TempFile::create(comphelper::getComponentContext(m_xFactory)),
     343           0 :                             uno::UNO_QUERY_THROW );
     344           0 :         uno::Reference < io::XInputStream > xTempIn( xTempOut, UNO_QUERY_THROW );
     345           0 :         uno::Reference < io::XSeekable > xTempSeek( xTempOut, UNO_QUERY_THROW );
     346             : 
     347             :         // copy the raw stream to the temporary file
     348           0 :         ::comphelper::OStorageHelper::CopyInputToOutput( xInRaw, xTempOut );
     349           0 :         xTempOut->closeOutput();
     350           0 :         xTempSeek->seek( 0 );
     351             : 
     352             :         // close raw stream, package stream and folder
     353           0 :         xInRaw = uno::Reference< io::XInputStream >();
     354           0 :         xNewPSProps = uno::Reference< XPropertySet >();
     355           0 :         xNPSTunnel = uno::Reference< XUnoTunnel >();
     356           0 :         xNewPackStream = uno::Reference< XDataSinkEncrSupport >();
     357           0 :         xTunnel = uno::Reference< XUnoTunnel >();
     358           0 :         xRootNameContainer = uno::Reference< container::XNameContainer >();
     359             : 
     360             :         // return the stream representing the first temporary file
     361           0 :         return xTempIn;
     362             :     }
     363           0 :     catch ( RuntimeException& )
     364             :     {
     365           0 :         throw;
     366             :     }
     367           0 :     catch ( Exception& )
     368             :     {
     369             :     }
     370             : 
     371           0 :     throw io::IOException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     372             : }
     373             : 
     374             : //--------------------------------------------------------------------------
     375           0 : sal_Bool ZipPackageStream::ParsePackageRawStream()
     376             : {
     377             :     OSL_ENSURE( GetOwnSeekStream().is(), "A stream must be provided!\n" );
     378             : 
     379           0 :     if ( !GetOwnSeekStream().is() )
     380           0 :         return sal_False;
     381             : 
     382           0 :     sal_Bool bOk = sal_False;
     383             : 
     384           0 :     ::rtl::Reference< BaseEncryptionData > xTempEncrData;
     385           0 :     sal_Int32 nMagHackSize = 0;
     386           0 :     Sequence < sal_Int8 > aHeader ( 4 );
     387             : 
     388             :     try
     389             :     {
     390           0 :         if ( GetOwnSeekStream()->readBytes ( aHeader, 4 ) == 4 )
     391             :         {
     392           0 :             const sal_Int8 *pHeader = aHeader.getConstArray();
     393           0 :             sal_uInt32 nHeader = ( pHeader [0] & 0xFF )       |
     394           0 :                                  ( pHeader [1] & 0xFF ) << 8  |
     395           0 :                                  ( pHeader [2] & 0xFF ) << 16 |
     396           0 :                                  ( pHeader [3] & 0xFF ) << 24;
     397           0 :             if ( nHeader == n_ConstHeader )
     398             :             {
     399             :                 // this is one of our god-awful, but extremely devious hacks, everyone cheer
     400           0 :                 xTempEncrData = new BaseEncryptionData;
     401             : 
     402           0 :                 OUString aMediaType;
     403           0 :                 sal_Int32 nEncAlgorithm = 0;
     404           0 :                 sal_Int32 nChecksumAlgorithm = 0;
     405           0 :                 sal_Int32 nDerivedKeySize = 0;
     406           0 :                 sal_Int32 nStartKeyGenID = 0;
     407           0 :                 if ( ZipFile::StaticFillData( xTempEncrData, nEncAlgorithm, nChecksumAlgorithm, nDerivedKeySize, nStartKeyGenID, nMagHackSize, aMediaType, GetOwnSeekStream() ) )
     408             :                 {
     409             :                     // We'll want to skip the data we've just read, so calculate how much we just read
     410             :                     // and remember it
     411           0 :                     m_nMagicalHackPos = n_ConstHeaderSize + xTempEncrData->m_aSalt.getLength()
     412           0 :                                                         + xTempEncrData->m_aInitVector.getLength()
     413           0 :                                                         + xTempEncrData->m_aDigest.getLength()
     414           0 :                                                         + aMediaType.getLength() * sizeof( sal_Unicode );
     415           0 :                     m_nImportedEncryptionAlgorithm = nEncAlgorithm;
     416           0 :                     m_nImportedChecksumAlgorithm = nChecksumAlgorithm;
     417           0 :                     m_nImportedDerivedKeySize = nDerivedKeySize;
     418           0 :                     m_nImportedStartKeyAlgorithm = nStartKeyGenID;
     419           0 :                     m_nMagicalHackSize = nMagHackSize;
     420           0 :                     sMediaType = aMediaType;
     421             : 
     422           0 :                     bOk = sal_True;
     423           0 :                 }
     424             :             }
     425             :         }
     426             :     }
     427           0 :     catch( Exception& )
     428             :     {
     429             :     }
     430             : 
     431           0 :     if ( !bOk )
     432             :     {
     433             :         // the provided stream is not a raw stream
     434           0 :         return sal_False;
     435             :     }
     436             : 
     437           0 :     m_xBaseEncryptionData = xTempEncrData;
     438           0 :     SetIsEncrypted ( sal_True );
     439             :     // it's already compressed and encrypted
     440           0 :     bToBeEncrypted = bToBeCompressed = sal_False;
     441             : 
     442           0 :     return sal_True;
     443             : }
     444             : 
     445        6087 : void ZipPackageStream::SetPackageMember( sal_Bool bNewValue )
     446             : {
     447        6087 :     if ( bNewValue )
     448             :     {
     449        5094 :         m_nStreamMode = PACKAGE_STREAM_PACKAGEMEMBER;
     450        5094 :         m_nMagicalHackPos = 0;
     451        5094 :         m_nMagicalHackSize = 0;
     452             :     }
     453         993 :     else if ( m_nStreamMode == PACKAGE_STREAM_PACKAGEMEMBER )
     454           0 :         m_nStreamMode = PACKAGE_STREAM_NOTSET; // must be reset
     455        6087 : }
     456             : 
     457             : // XActiveDataSink
     458             : //--------------------------------------------------------------------------
     459         993 : void SAL_CALL ZipPackageStream::setInputStream( const uno::Reference< io::XInputStream >& aStream )
     460             :         throw( RuntimeException )
     461             : {
     462             :     // if seekable access is required the wrapping will be done on demand
     463         993 :     xStream = aStream;
     464         993 :     m_nImportedEncryptionAlgorithm = 0;
     465         993 :     m_bHasSeekable = sal_False;
     466         993 :     SetPackageMember ( sal_False );
     467         993 :     aEntry.nTime = -1;
     468         993 :     m_nStreamMode = PACKAGE_STREAM_DETECT;
     469         993 : }
     470             : 
     471             : //--------------------------------------------------------------------------
     472         235 : uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawData()
     473             :         throw( RuntimeException )
     474             : {
     475             :     try
     476             :     {
     477         235 :         if ( IsPackageMember() )
     478             :         {
     479           0 :             return rZipPackage.getZipFile().getRawData( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
     480             :         }
     481         235 :         else if ( GetOwnSeekStream().is() )
     482             :         {
     483         235 :             return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
     484             :         }
     485             :         else
     486           0 :             return uno::Reference < io::XInputStream > ();
     487             :     }
     488           0 :     catch ( ZipException & )//rException )
     489             :     {
     490             :         OSL_FAIL( "ZipException thrown" );//rException.Message);
     491           0 :         return uno::Reference < io::XInputStream > ();
     492             :     }
     493           0 :     catch ( Exception & )
     494             :     {
     495             :         OSL_FAIL( "Exception is thrown during stream wrapping!\n" );
     496           0 :         return uno::Reference < io::XInputStream > ();
     497             :     }
     498             : }
     499             : 
     500             : //--------------------------------------------------------------------------
     501         325 : uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getInputStream()
     502             :         throw( RuntimeException )
     503             : {
     504             :     try
     505             :     {
     506         325 :         if ( IsPackageMember() )
     507             :         {
     508         325 :             return rZipPackage.getZipFile().getInputStream( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
     509             :         }
     510           0 :         else if ( GetOwnSeekStream().is() )
     511             :         {
     512           0 :             return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
     513             :         }
     514             :         else
     515           0 :             return uno::Reference < io::XInputStream > ();
     516             :     }
     517           0 :     catch ( ZipException & )//rException )
     518             :     {
     519             :         OSL_FAIL( "ZipException thrown" );//rException.Message);
     520           0 :         return uno::Reference < io::XInputStream > ();
     521             :     }
     522           0 :     catch ( Exception &ex )
     523             :     {
     524             :         OSL_FAIL( "Exception is thrown during stream wrapping!\n" );
     525             :         OSL_FAIL(OUStringToOString(ex.Message, RTL_TEXTENCODING_UTF8).getStr());
     526             :         (void)ex;
     527           0 :         return uno::Reference < io::XInputStream > ();
     528             :     }
     529             : }
     530             : 
     531             : // XDataSinkEncrSupport
     532             : //--------------------------------------------------------------------------
     533        2322 : uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream()
     534             :         throw ( packages::WrongPasswordException,
     535             :                 io::IOException,
     536             :                 RuntimeException )
     537             : {
     538             :     // There is no stream attached to this object
     539        2322 :     if ( m_nStreamMode == PACKAGE_STREAM_NOTSET )
     540         326 :         return uno::Reference< io::XInputStream >();
     541             : 
     542             :     // this method can not be used together with old approach
     543        1996 :     if ( m_nStreamMode == PACKAGE_STREAM_DETECT )
     544           0 :         throw packages::zip::ZipIOException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     545             : 
     546        1996 :     if ( IsPackageMember() )
     547             :     {
     548        1971 :         uno::Reference< io::XInputStream > xResult;
     549             :         try
     550             :         {
     551        1971 :             xResult = rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
     552             :         }
     553           0 :         catch( packages::WrongPasswordException& )
     554             :         {
     555             :             // workaround for the encrypted documents generated with the old OOo1.x bug.
     556           0 :             if ( rZipPackage.GetStartKeyGenID() == xml::crypto::DigestID::SHA1 && !m_bUseWinEncoding )
     557             :             {
     558           0 :                 xResult = rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData( true ), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
     559           0 :                 m_bUseWinEncoding = true;
     560             :             }
     561             :             else
     562           0 :                 throw;
     563             :         }
     564        1971 :         return xResult;
     565             :     }
     566          25 :     else if ( m_nStreamMode == PACKAGE_STREAM_RAW )
     567           0 :         return ZipFile::StaticGetDataFromRawStream( comphelper::getComponentContext(m_xFactory), GetOwnSeekStream(), GetEncryptionData() );
     568          25 :     else if ( GetOwnSeekStream().is() )
     569             :     {
     570          25 :         return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
     571             :     }
     572             :     else
     573           0 :         return uno::Reference< io::XInputStream >();
     574             : }
     575             : 
     576             : //--------------------------------------------------------------------------
     577           0 : uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawStream()
     578             :         throw ( packages::NoEncryptionException,
     579             :                 io::IOException,
     580             :                 uno::RuntimeException )
     581             : {
     582             :     // There is no stream attached to this object
     583           0 :     if ( m_nStreamMode == PACKAGE_STREAM_NOTSET )
     584           0 :         return uno::Reference< io::XInputStream >();
     585             : 
     586             :     // this method can not be used together with old approach
     587           0 :     if ( m_nStreamMode == PACKAGE_STREAM_DETECT )
     588           0 :         throw packages::zip::ZipIOException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     589             : 
     590           0 :     if ( IsPackageMember() )
     591             :     {
     592           0 :         if ( !bIsEncrypted || !GetEncryptionData().is() )
     593           0 :             throw packages::NoEncryptionException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     594             : 
     595           0 :         return rZipPackage.getZipFile().getWrappedRawStream( aEntry, GetEncryptionData(), sMediaType, rZipPackage.GetSharedMutexRef() );
     596             :     }
     597           0 :     else if ( GetOwnSeekStream().is() )
     598             :     {
     599           0 :         if ( m_nStreamMode == PACKAGE_STREAM_RAW )
     600             :         {
     601           0 :             return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() );
     602             :         }
     603           0 :         else if ( m_nStreamMode == PACKAGE_STREAM_DATA && bToBeEncrypted )
     604           0 :             return TryToGetRawFromDataStream( sal_True );
     605             :     }
     606             : 
     607           0 :     throw packages::NoEncryptionException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     608             : }
     609             : 
     610             : 
     611             : //--------------------------------------------------------------------------
     612         993 : void SAL_CALL ZipPackageStream::setDataStream( const uno::Reference< io::XInputStream >& aStream )
     613             :         throw ( io::IOException,
     614             :                 RuntimeException )
     615             : {
     616         993 :     setInputStream( aStream );
     617         993 :     m_nStreamMode = PACKAGE_STREAM_DATA;
     618         993 : }
     619             : 
     620             : //--------------------------------------------------------------------------
     621           0 : void SAL_CALL ZipPackageStream::setRawStream( const uno::Reference< io::XInputStream >& aStream )
     622             :         throw ( packages::EncryptionNotAllowedException,
     623             :                 packages::NoRawFormatException,
     624             :                 io::IOException,
     625             :                 RuntimeException )
     626             : {
     627             :     // wrap the stream in case it is not seekable
     628           0 :     uno::Reference< io::XInputStream > xNewStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( aStream, comphelper::getComponentContext( m_xFactory ) );
     629           0 :     uno::Reference< io::XSeekable > xSeek( xNewStream, UNO_QUERY );
     630           0 :     if ( !xSeek.is() )
     631             :         throw RuntimeException(OSL_LOG_PREFIX "The stream must support XSeekable!",
     632           0 :                                     uno::Reference< XInterface >() );
     633             : 
     634           0 :     xSeek->seek( 0 );
     635           0 :     uno::Reference< io::XInputStream > xOldStream = xStream;
     636           0 :     xStream = xNewStream;
     637           0 :     if ( !ParsePackageRawStream() )
     638             :     {
     639           0 :         xStream = xOldStream;
     640           0 :         throw packages::NoRawFormatException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     641             :     }
     642             : 
     643             :     // the raw stream MUST have seekable access
     644           0 :     m_bHasSeekable = sal_True;
     645             : 
     646           0 :     SetPackageMember ( sal_False );
     647           0 :     aEntry.nTime = -1;
     648           0 :     m_nStreamMode = PACKAGE_STREAM_RAW;
     649           0 : }
     650             : 
     651             : //--------------------------------------------------------------------------
     652           0 : uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getPlainRawStream()
     653             :         throw ( io::IOException,
     654             :                 uno::RuntimeException )
     655             : {
     656             :     // There is no stream attached to this object
     657           0 :     if ( m_nStreamMode == PACKAGE_STREAM_NOTSET )
     658           0 :         return uno::Reference< io::XInputStream >();
     659             : 
     660             :     // this method can not be used together with old approach
     661           0 :     if ( m_nStreamMode == PACKAGE_STREAM_DETECT )
     662           0 :         throw packages::zip::ZipIOException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     663             : 
     664           0 :     if ( IsPackageMember() )
     665             :     {
     666           0 :         return rZipPackage.getZipFile().getRawData( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() );
     667             :     }
     668           0 :     else if ( GetOwnSeekStream().is() )
     669             :     {
     670           0 :         if ( m_nStreamMode == PACKAGE_STREAM_RAW )
     671             :         {
     672             :             // the header should not be returned here
     673           0 :             return GetRawEncrStreamNoHeaderCopy();
     674             :         }
     675           0 :         else if ( m_nStreamMode == PACKAGE_STREAM_DATA )
     676           0 :             return TryToGetRawFromDataStream( sal_False );
     677             :     }
     678             : 
     679           0 :     return uno::Reference< io::XInputStream >();
     680             : }
     681             : 
     682             : // XUnoTunnel
     683             : 
     684             : //--------------------------------------------------------------------------
     685        4502 : sal_Int64 SAL_CALL ZipPackageStream::getSomething( const Sequence< sal_Int8 >& aIdentifier )
     686             :     throw( RuntimeException )
     687             : {
     688        4502 :     sal_Int64 nMe = 0;
     689        9004 :     if ( aIdentifier.getLength() == 16 &&
     690        4502 :          0 == memcmp( static_getImplementationId().getConstArray(), aIdentifier.getConstArray(), 16 ) )
     691        3144 :         nMe = reinterpret_cast < sal_Int64 > ( this );
     692        4502 :     return nMe;
     693             : }
     694             : 
     695             : // XPropertySet
     696             : //--------------------------------------------------------------------------
     697        4741 : void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
     698             :         throw( beans::UnknownPropertyException, beans::PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
     699             : {
     700        4741 :     if ( aPropertyName == "MediaType" )
     701             :     {
     702        1067 :         if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE && rZipPackage.getFormat() != embed::StorageFormats::OFOPXML )
     703           0 :             throw beans::PropertyVetoException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     704             : 
     705        1067 :         if ( aValue >>= sMediaType )
     706             :         {
     707        1067 :             if ( !sMediaType.isEmpty() )
     708             :             {
     709        1045 :                 if ( sMediaType.indexOf ( "text" ) != -1
     710         222 :                  || sMediaType == "application/vnd.sun.star.oleobject" )
     711         614 :                     bToBeCompressed = sal_True;
     712         209 :                 else if ( !m_bCompressedIsSetFromOutside )
     713         209 :                     bToBeCompressed = sal_False;
     714             :             }
     715             :         }
     716             :         else
     717             :             throw IllegalArgumentException(OSL_LOG_PREFIX "MediaType must be a string!\n",
     718             :                                             uno::Reference< XInterface >(),
     719           0 :                                             2 );
     720             : 
     721             :     }
     722        3674 :     else if ( aPropertyName == "Size" )
     723             :     {
     724           0 :         if ( !( aValue >>= aEntry.nSize ) )
     725             :             throw IllegalArgumentException(OSL_LOG_PREFIX "Wrong type for Size property!\n",
     726             :                                             uno::Reference< XInterface >(),
     727           0 :                                             2 );
     728             :     }
     729        3674 :     else if ( aPropertyName == "Encrypted" )
     730             :     {
     731        1730 :         if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
     732           0 :             throw beans::PropertyVetoException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     733             : 
     734        1730 :         sal_Bool bEnc = sal_False;
     735        1730 :         if ( aValue >>= bEnc )
     736             :         {
     737             :             // In case of new raw stream, the stream must not be encrypted on storing
     738        1730 :             if ( bEnc && m_nStreamMode == PACKAGE_STREAM_RAW )
     739             :                 throw IllegalArgumentException(OSL_LOG_PREFIX "Raw stream can not be encrypted on storing",
     740             :                                                 uno::Reference< XInterface >(),
     741           0 :                                                 2 );
     742             : 
     743        1730 :             bToBeEncrypted = bEnc;
     744        1730 :             if ( bToBeEncrypted && !m_xBaseEncryptionData.is() )
     745         791 :                 m_xBaseEncryptionData = new BaseEncryptionData;
     746             :         }
     747             :         else
     748             :             throw IllegalArgumentException(OSL_LOG_PREFIX "Wrong type for Encrypted property!\n",
     749             :                                             uno::Reference< XInterface >(),
     750           0 :                                             2 );
     751             : 
     752             :     }
     753        1944 :     else if ( aPropertyName == ENCRYPTION_KEY_PROPERTY )
     754             :     {
     755           0 :         if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
     756           0 :             throw beans::PropertyVetoException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     757             : 
     758           0 :         uno::Sequence< sal_Int8 > aNewKey;
     759             : 
     760           0 :         if ( !( aValue >>= aNewKey ) )
     761             :         {
     762           0 :             OUString sTempString;
     763           0 :             if ( ( aValue >>= sTempString ) )
     764             :             {
     765           0 :                 sal_Int32 nPathLength = sTempString.getLength();
     766           0 :                 Sequence < sal_Int8 > aSequence ( nPathLength );
     767           0 :                 sal_Int8 *pArray = aSequence.getArray();
     768           0 :                 const sal_Unicode *pChar = sTempString.getStr();
     769           0 :                 for ( sal_Int16 i = 0; i < nPathLength; i++ )
     770           0 :                     pArray[i] = static_cast < const sal_Int8 > ( pChar[i] );
     771           0 :                 aNewKey = aSequence;
     772             :             }
     773             :             else
     774             :                 throw IllegalArgumentException(OSL_LOG_PREFIX "Wrong type for EncryptionKey property!\n",
     775             :                                                 uno::Reference< XInterface >(),
     776           0 :                                                 2 );
     777             :         }
     778             : 
     779           0 :         if ( aNewKey.getLength() )
     780             :         {
     781           0 :             if ( !m_xBaseEncryptionData.is() )
     782           0 :                 m_xBaseEncryptionData = new BaseEncryptionData;
     783             : 
     784           0 :             m_aEncryptionKey = aNewKey;
     785             :             // In case of new raw stream, the stream must not be encrypted on storing
     786           0 :             bHaveOwnKey = sal_True;
     787           0 :             if ( m_nStreamMode != PACKAGE_STREAM_RAW )
     788           0 :                 bToBeEncrypted = sal_True;
     789             :         }
     790             :         else
     791             :         {
     792           0 :             bHaveOwnKey = sal_False;
     793           0 :             m_aEncryptionKey.realloc( 0 );
     794             :         }
     795             : 
     796           0 :         m_aStorageEncryptionKeys.realloc( 0 );
     797             :     }
     798        1944 :     else if ( aPropertyName == STORAGE_ENCRYPTION_KEYS_PROPERTY )
     799             :     {
     800         877 :         if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
     801           0 :             throw beans::PropertyVetoException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     802             : 
     803         877 :         uno::Sequence< beans::NamedValue > aKeys;
     804         877 :         if ( !( aValue >>= aKeys ) )
     805             :         {
     806             :                 throw IllegalArgumentException(OSL_LOG_PREFIX "Wrong type for StorageEncryptionKeys property!\n",
     807             :                                                 uno::Reference< XInterface >(),
     808           0 :                                                 2 );
     809             :         }
     810             : 
     811         877 :         if ( aKeys.getLength() )
     812             :         {
     813          12 :             if ( !m_xBaseEncryptionData.is() )
     814           0 :                 m_xBaseEncryptionData = new BaseEncryptionData;
     815             : 
     816          12 :             m_aStorageEncryptionKeys = aKeys;
     817             : 
     818             :             // In case of new raw stream, the stream must not be encrypted on storing
     819          12 :             bHaveOwnKey = sal_True;
     820          12 :             if ( m_nStreamMode != PACKAGE_STREAM_RAW )
     821          12 :                 bToBeEncrypted = sal_True;
     822             :         }
     823             :         else
     824             :         {
     825         865 :             bHaveOwnKey = sal_False;
     826         865 :             m_aStorageEncryptionKeys.realloc( 0 );
     827             :         }
     828             : 
     829         877 :         m_aEncryptionKey.realloc( 0 );
     830             :     }
     831        1067 :     else if ( aPropertyName == "Compressed" )
     832             :     {
     833        1067 :         sal_Bool bCompr = sal_False;
     834             : 
     835        1067 :         if ( aValue >>= bCompr )
     836             :         {
     837             :             // In case of new raw stream, the stream must not be encrypted on storing
     838        1067 :             if ( bCompr && m_nStreamMode == PACKAGE_STREAM_RAW )
     839             :                 throw IllegalArgumentException(OSL_LOG_PREFIX "Raw stream can not be encrypted on storing",
     840             :                                                 uno::Reference< XInterface >(),
     841           0 :                                                 2 );
     842             : 
     843        1067 :             bToBeCompressed = bCompr;
     844        1067 :             m_bCompressedIsSetFromOutside = sal_True;
     845             :         }
     846             :         else
     847             :             throw IllegalArgumentException(OSL_LOG_PREFIX "Wrong type for Compressed property!\n",
     848             :                                             uno::Reference< XInterface >(),
     849           0 :                                             2 );
     850             :     }
     851             :     else
     852           0 :         throw beans::UnknownPropertyException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     853        4741 : }
     854             : 
     855             : //--------------------------------------------------------------------------
     856        9118 : Any SAL_CALL ZipPackageStream::getPropertyValue( const OUString& PropertyName )
     857             :         throw( beans::UnknownPropertyException, WrappedTargetException, RuntimeException )
     858             : {
     859        9118 :     Any aAny;
     860        9118 :     if ( PropertyName == "MediaType" )
     861             :     {
     862        2130 :         aAny <<= sMediaType;
     863        2130 :         return aAny;
     864             :     }
     865        6988 :     else if ( PropertyName == "Size" )
     866             :     {
     867        2491 :         aAny <<= aEntry.nSize;
     868        2491 :         return aAny;
     869             :     }
     870        4497 :     else if ( PropertyName == "Encrypted" )
     871             :     {
     872         969 :         aAny <<= ((m_nStreamMode == PACKAGE_STREAM_RAW) ? sal_True : bToBeEncrypted);
     873         969 :         return aAny;
     874             :     }
     875        3528 :     else if ( PropertyName == "WasEncrypted" )
     876             :     {
     877        1013 :         aAny <<= bIsEncrypted;
     878        1013 :         return aAny;
     879             :     }
     880        2515 :     else if ( PropertyName == "Compressed" )
     881             :     {
     882        2491 :         aAny <<= bToBeCompressed;
     883        2491 :         return aAny;
     884             :     }
     885          24 :     else if ( PropertyName == ENCRYPTION_KEY_PROPERTY )
     886             :     {
     887           0 :         aAny <<= m_aEncryptionKey;
     888           0 :         return aAny;
     889             :     }
     890          24 :     else if ( PropertyName == STORAGE_ENCRYPTION_KEYS_PROPERTY )
     891             :     {
     892          24 :         aAny <<= m_aStorageEncryptionKeys;
     893          24 :         return aAny;
     894             :     }
     895             :     else
     896           0 :         throw beans::UnknownPropertyException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     897             : }
     898             : 
     899             : //--------------------------------------------------------------------------
     900          18 : void ZipPackageStream::setSize ( const sal_Int64 nNewSize )
     901             : {
     902          18 :     if ( aEntry.nCompressedSize != nNewSize )
     903          18 :         aEntry.nMethod = DEFLATED;
     904          18 :     aEntry.nSize = nNewSize;
     905          18 : }
     906             : //--------------------------------------------------------------------------
     907           0 : OUString ZipPackageStream::getImplementationName()
     908             :     throw ( RuntimeException )
     909             : {
     910           0 :     return OUString ("ZipPackageStream");
     911             : }
     912             : 
     913             : //--------------------------------------------------------------------------
     914           0 : Sequence< OUString > ZipPackageStream::getSupportedServiceNames()
     915             :     throw ( RuntimeException )
     916             : {
     917           0 :     Sequence< OUString > aNames( 1 );
     918           0 :     aNames[0] = "com.sun.star.packages.PackageStream";
     919           0 :     return aNames;
     920             : }
     921             : //--------------------------------------------------------------------------
     922           0 : sal_Bool SAL_CALL ZipPackageStream::supportsService( OUString const & rServiceName )
     923             :     throw ( RuntimeException )
     924             : {
     925           0 :     return rServiceName == getSupportedServiceNames()[0];
     926             : }
     927             : 
     928             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10