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

Generated by: LCOV version 1.10