LibreOffice Module package (master) 1
ZipPackageStream.cxx
Go to the documentation of this file.
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#include <ZipPackageStream.hxx>
21
22#include <com/sun/star/beans/PropertyValue.hpp>
23#include <com/sun/star/container/XNameContainer.hpp>
24#include <com/sun/star/packages/NoRawFormatException.hpp>
25#include <com/sun/star/packages/zip/ZipConstants.hpp>
26#include <com/sun/star/embed/StorageFormats.hpp>
27#include <com/sun/star/packages/zip/ZipIOException.hpp>
28#include <com/sun/star/packages/NoEncryptionException.hpp>
29#include <com/sun/star/packages/zip/ZipException.hpp>
30#include <com/sun/star/packages/WrongPasswordException.hpp>
31#include <com/sun/star/io/TempFile.hpp>
32#include <com/sun/star/io/XInputStream.hpp>
33#include <com/sun/star/io/XOutputStream.hpp>
34#include <com/sun/star/io/XStream.hpp>
35#include <com/sun/star/io/XSeekable.hpp>
36#include <com/sun/star/xml/crypto/DigestID.hpp>
37#include <com/sun/star/xml/crypto/CipherID.hpp>
38
39#include <CRC32.hxx>
40#include <ZipOutputEntry.hxx>
41#include <ZipOutputStream.hxx>
42#include <ZipPackage.hxx>
43#include <ZipFile.hxx>
45#include <osl/diagnose.h>
47
52#include <unotools/tempfile.hxx>
53
54#include <rtl/random.h>
55#include <sal/log.hxx>
57
58#include <PackageConstants.hxx>
59
60#include <algorithm>
61#include <cstddef>
62
63using namespace com::sun::star::packages::zip::ZipConstants;
64using namespace com::sun::star::packages::zip;
65using namespace com::sun::star::uno;
66using namespace com::sun::star::lang;
67using namespace com::sun::star;
68using namespace cppu;
69
70#if OSL_DEBUG_LEVEL > 0
71#define THROW_WHERE SAL_WHERE
72#else
73#define THROW_WHERE ""
74#endif
75
77 const uno::Reference< XComponentContext >& xContext,
78 sal_Int32 nFormat,
79 bool bAllowRemoveOnInsert )
80: m_rZipPackage( rNewPackage )
81, m_bToBeCompressed ( true )
82, m_bToBeEncrypted ( false )
83, m_bHaveOwnKey ( false )
84, m_bIsEncrypted ( false )
85, m_nImportedStartKeyAlgorithm( 0 )
86, m_nImportedEncryptionAlgorithm( 0 )
87, m_nImportedChecksumAlgorithm( 0 )
88, m_nImportedDerivedKeySize( 0 )
89, m_nStreamMode( PACKAGE_STREAM_NOTSET )
90, m_nMagicalHackPos( 0 )
91, m_nMagicalHackSize( 0 )
92, m_nOwnStreamOrigSize( 0 )
93, m_bHasSeekable( false )
94, m_bCompressedIsSetFromOutside( false )
95, m_bFromManifest( false )
96, m_bUseWinEncoding( false )
97, m_bRawStream( false )
98{
99 m_xContext = xContext;
100 m_nFormat = nFormat;
101 mbAllowRemoveOnInsert = bAllowRemoveOnInsert;
102 SetFolder ( false );
103 aEntry.nVersion = -1;
104 aEntry.nFlag = 0;
105 aEntry.nMethod = -1;
106 aEntry.nTime = -1;
107 aEntry.nCrc = -1;
108 aEntry.nCompressedSize = -1;
109 aEntry.nSize = -1;
110 aEntry.nOffset = -1;
111 aEntry.nPathLen = -1;
112 aEntry.nExtraLen = -1;
113}
114
116{
117}
118
120{
121 aEntry.nVersion = rInEntry.nVersion;
122 aEntry.nFlag = rInEntry.nFlag;
123 aEntry.nMethod = rInEntry.nMethod;
124 aEntry.nTime = rInEntry.nTime;
125 aEntry.nCrc = rInEntry.nCrc;
126 aEntry.nCompressedSize = rInEntry.nCompressedSize;
127 aEntry.nSize = rInEntry.nSize;
128 aEntry.nOffset = rInEntry.nOffset;
129 aEntry.sPath = rInEntry.sPath;
130 aEntry.nPathLen = rInEntry.nPathLen;
131 aEntry.nExtraLen = rInEntry.nExtraLen;
132
133 if ( aEntry.nMethod == STORED )
134 m_bToBeCompressed = false;
135}
136
137uno::Reference< io::XInputStream > const & ZipPackageStream::GetOwnSeekStream()
138{
139 if ( !m_bHasSeekable && m_xStream.is() )
140 {
141 // The package component requires that every stream either be FROM a package or it must support XSeekable!
142 // The only exception is a nonseekable stream that is provided only for storing, if such a stream
143 // is accessed before commit it MUST be wrapped.
144 // Wrap the stream in case it is not seekable
146 uno::Reference< io::XSeekable > xSeek( m_xStream, UNO_QUERY_THROW );
147
148 m_bHasSeekable = true;
149 }
150
151 return m_xStream;
152}
153
154uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCopy()
155{
157 throw io::IOException(THROW_WHERE );
158
159 if ( m_xBaseEncryptionData.is() )
160 throw ZipIOException(THROW_WHERE "Encrypted stream without encryption data!" );
161
162 uno::Reference< io::XSeekable > xSeek( GetOwnSeekStream(), UNO_QUERY );
163 if ( !xSeek.is() )
164 throw ZipIOException(THROW_WHERE "The stream must be seekable!" );
165
166 // skip header
167 xSeek->seek( n_ConstHeaderSize + m_xBaseEncryptionData->m_aInitVector.getLength() +
168 m_xBaseEncryptionData->m_aSalt.getLength() + m_xBaseEncryptionData->m_aDigest.getLength() );
169
170 // create temporary stream
172 uno::Reference < io::XInputStream > xTempIn = xTempFile->getInputStream();
173
174 // copy the raw stream to the temporary file starting from the current position
176 xTempFile->closeOutput();
177 xTempFile->seek( 0 );
178
179 return xTempIn;
180}
181
183{
185}
186
188{
189 return GetEncryptionAlgorithm() == css::xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 16 : 8;
190}
191
193{
195 if ( m_xBaseEncryptionData.is() )
196 xResult = new EncryptionData(
198 GetEncryptionKey(bugs),
203 bugs != Bugs::None);
204
205 return xResult;
206}
207
208uno::Sequence<sal_Int8> ZipPackageStream::GetEncryptionKey(Bugs const bugs)
209{
210 uno::Sequence< sal_Int8 > aResult;
211 sal_Int32 nKeyGenID = GetStartKeyGenID();
212 bool const bUseWinEncoding = (bugs == Bugs::WinEncodingWrongSHA1 || m_bUseWinEncoding);
213
214 if ( m_bHaveOwnKey && m_aStorageEncryptionKeys.hasElements() )
215 {
216 OUString aNameToFind;
217 if ( nKeyGenID == xml::crypto::DigestID::SHA256 )
219 else if ( nKeyGenID == xml::crypto::DigestID::SHA1 )
220 {
221 aNameToFind = bUseWinEncoding
223 : (bugs == Bugs::WrongSHA1)
226 }
227 else
228 throw uno::RuntimeException(THROW_WHERE "No expected key is provided!" );
229
230 for ( const auto& rKey : std::as_const(m_aStorageEncryptionKeys) )
231 if ( rKey.Name == aNameToFind )
232 rKey.Value >>= aResult;
233
234 // empty keys are not allowed here
235 // so it is not important whether there is no key, or the key is empty, it is an error
236 if ( !aResult.hasElements() )
237 throw uno::RuntimeException(THROW_WHERE "No expected key is provided!" );
238 }
239 else
240 aResult = m_aEncryptionKey;
241
242 if ( !aResult.hasElements() || !m_bHaveOwnKey )
244
245 return aResult;
246}
247
249{
250 // generally should all the streams use the same Start Key
251 // but if raw copy without password takes place, we should preserve the imported algorithm
253}
254
255uno::Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( bool bAddHeaderForEncr )
256{
257 if ( m_nStreamMode != PACKAGE_STREAM_DATA || !GetOwnSeekStream().is() || ( bAddHeaderForEncr && !m_bToBeEncrypted ) )
258 throw packages::NoEncryptionException(THROW_WHERE );
259
261
262 if ( m_bToBeEncrypted )
263 {
264 aKey = GetEncryptionKey();
265 if ( !aKey.hasElements() )
266 throw packages::NoEncryptionException(THROW_WHERE );
267 }
268
269 try
270 {
271 // create temporary file
272 uno::Reference < io::XStream > xTempStream(new utl::TempFileFastService);
273
274 // create a package based on it
276
277 Sequence< Any > aArgs{ Any(xTempStream) };
278 pPackage->initialize( aArgs );
279
280 // create a new package stream
281 uno::Reference< XDataSinkEncrSupport > xNewPackStream( pPackage->createInstance(), UNO_QUERY_THROW );
282 xNewPackStream->setDataStream(
284
285 uno::Reference< XPropertySet > xNewPSProps( xNewPackStream, UNO_QUERY_THROW );
286
287 // copy all the properties of this stream to the new stream
288 xNewPSProps->setPropertyValue("MediaType", Any( msMediaType ) );
289 xNewPSProps->setPropertyValue("Compressed", Any( m_bToBeCompressed ) );
290 if ( m_bToBeEncrypted )
291 {
292 xNewPSProps->setPropertyValue(ENCRYPTION_KEY_PROPERTY, Any( aKey ) );
293 xNewPSProps->setPropertyValue("Encrypted", Any( true ) );
294 }
295
296 // insert a new stream in the package
297 uno::Reference< XInterface > xTmp;
298 Any aRoot = pPackage->getByHierarchicalName("/");
299 aRoot >>= xTmp;
300 uno::Reference< container::XNameContainer > xRootNameContainer( xTmp, UNO_QUERY_THROW );
301
302 uno::Reference< XInterface > xNPSDummy( xNewPackStream, UNO_QUERY );
303 xRootNameContainer->insertByName("dummy", Any( xNPSDummy ) );
304
305 // commit the temporary package
306 pPackage->commitChanges();
307
308 // get raw stream from the temporary package
309 uno::Reference< io::XInputStream > xInRaw;
310 if ( bAddHeaderForEncr )
311 xInRaw = xNewPackStream->getRawStream();
312 else
313 xInRaw = xNewPackStream->getPlainRawStream();
314
315 // create another temporary file
317 uno::Reference < io::XInputStream > xTempIn( xTempOut );
318
319 // copy the raw stream to the temporary file
321 xTempOut->closeOutput();
322 xTempOut->seek( 0 );
323
324 // close raw stream, package stream and folder
325 xInRaw.clear();
326 xNewPSProps.clear();
327 xNPSDummy.clear();
328 xNewPackStream.clear();
329 xTmp.clear();
330 xRootNameContainer.clear();
331
332 // return the stream representing the first temporary file
333 return xTempIn;
334 }
335 catch ( RuntimeException& )
336 {
337 throw;
338 }
339 catch ( Exception& )
340 {
341 }
342
343 throw io::IOException(THROW_WHERE );
344}
345
347{
348 OSL_ENSURE( GetOwnSeekStream().is(), "A stream must be provided!" );
349
350 if ( !GetOwnSeekStream().is() )
351 return false;
352
353 bool bOk = false;
354
356 Sequence < sal_Int8 > aHeader ( 4 );
357
358 try
359 {
360 if ( GetOwnSeekStream()->readBytes ( aHeader, 4 ) == 4 )
361 {
362 const sal_Int8 *pHeader = aHeader.getConstArray();
363 sal_uInt32 nHeader = ( pHeader [0] & 0xFF ) |
364 ( pHeader [1] & 0xFF ) << 8 |
365 ( pHeader [2] & 0xFF ) << 16 |
366 ( pHeader [3] & 0xFF ) << 24;
367 if ( nHeader == n_ConstHeader )
368 {
369 // this is one of our god-awful, but extremely devious hacks, everyone cheer
370 xTempEncrData = new BaseEncryptionData;
371
372 OUString aMediaType;
373 sal_Int32 nEncAlgorithm = 0;
374 sal_Int32 nChecksumAlgorithm = 0;
375 sal_Int32 nDerivedKeySize = 0;
376 sal_Int32 nStartKeyGenID = 0;
377 sal_Int32 nMagHackSize = 0;
378 if ( ZipFile::StaticFillData( xTempEncrData, nEncAlgorithm, nChecksumAlgorithm, nDerivedKeySize, nStartKeyGenID, nMagHackSize, aMediaType, GetOwnSeekStream() ) )
379 {
380 // We'll want to skip the data we've just read, so calculate how much we just read
381 // and remember it
382 m_nMagicalHackPos = n_ConstHeaderSize + xTempEncrData->m_aSalt.getLength()
383 + xTempEncrData->m_aInitVector.getLength()
384 + xTempEncrData->m_aDigest.getLength()
385 + aMediaType.getLength() * sizeof( sal_Unicode );
386 m_nImportedEncryptionAlgorithm = nEncAlgorithm;
387 m_nImportedChecksumAlgorithm = nChecksumAlgorithm;
388 m_nImportedDerivedKeySize = nDerivedKeySize;
389 m_nImportedStartKeyAlgorithm = nStartKeyGenID;
390 m_nMagicalHackSize = nMagHackSize;
391 msMediaType = aMediaType;
392
393 bOk = true;
394 }
395 }
396 }
397 }
398 catch( Exception& )
399 {
400 }
401
402 if ( !bOk )
403 {
404 // the provided stream is not a raw stream
405 return false;
406 }
407
408 m_xBaseEncryptionData = xTempEncrData;
409 SetIsEncrypted ( true );
410 // it's already compressed and encrypted
412
413 return true;
414}
415
416static void ImplSetStoredData( ZipEntry & rEntry, uno::Reference< io::XInputStream> const & rStream )
417{
418 // It's very annoying that we have to do this, but lots of zip packages
419 // don't allow data descriptors for STORED streams, meaning we have to
420 // know the size and CRC32 of uncompressed streams before we actually
421 // write them !
422 CRC32 aCRC32;
423 rEntry.nMethod = STORED;
424 rEntry.nCompressedSize = rEntry.nSize = aCRC32.updateStream ( rStream );
425 rEntry.nCrc = aCRC32.getValue();
426}
427
429 const OUString &rPath,
430 std::vector < uno::Sequence < beans::PropertyValue > > &rManList,
431 ZipOutputStream & rZipOut,
432 const uno::Sequence < sal_Int8 >& rEncryptionKey,
433 sal_Int32 nPBKDF2IterationCount,
434 const rtlRandomPool &rRandomPool)
435{
436 bool bSuccess = true;
437
438 static constexpr OUStringLiteral sDigestProperty (u"Digest");
439 static constexpr OUStringLiteral sEncryptionAlgProperty (u"EncryptionAlgorithm");
440 static constexpr OUStringLiteral sStartKeyAlgProperty (u"StartKeyAlgorithm");
441 static constexpr OUStringLiteral sDigestAlgProperty (u"DigestAlgorithm");
442 static constexpr OUStringLiteral sDerivedKeySizeProperty (u"DerivedKeySize");
443
444 uno::Sequence < beans::PropertyValue > aPropSet (PKG_SIZE_NOENCR_MNFST);
445
446 // In case the entry we are reading is also the entry we are writing, we will
447 // store the ZipEntry data in pTempEntry
448
449 // if pTempEntry is necessary, it will be released and passed to the ZipOutputStream
450 // and be deleted in the ZipOutputStream destructor
451 std::unique_ptr < ZipEntry > pAutoTempEntry ( new ZipEntry(aEntry) );
452 ZipEntry* pTempEntry = pAutoTempEntry.get();
453
454 pTempEntry->sPath = rPath;
455 pTempEntry->nPathLen = static_cast<sal_Int16>( OUStringToOString( pTempEntry->sPath, RTL_TEXTENCODING_UTF8 ).getLength() );
456
457 const bool bToBeEncrypted = m_bToBeEncrypted && (rEncryptionKey.hasElements() || m_bHaveOwnKey);
458 const bool bToBeCompressed = bToBeEncrypted || m_bToBeCompressed;
459
460 auto pPropSet = aPropSet.getArray();
461 pPropSet[PKG_MNFST_MEDIATYPE].Name = "MediaType";
462 pPropSet[PKG_MNFST_MEDIATYPE].Value <<= GetMediaType( );
463 pPropSet[PKG_MNFST_VERSION].Name = "Version";
464 pPropSet[PKG_MNFST_VERSION].Value <<= OUString(); // no version is stored for streams currently
465 pPropSet[PKG_MNFST_FULLPATH].Name = "FullPath";
466 pPropSet[PKG_MNFST_FULLPATH].Value <<= pTempEntry->sPath;
467
468 OSL_ENSURE( m_nStreamMode != PACKAGE_STREAM_NOTSET, "Unacceptable ZipPackageStream mode!" );
469
470 m_bRawStream = false;
473 else if ( m_nStreamMode == PACKAGE_STREAM_RAW )
474 m_bRawStream = true;
475
476 bool bBackgroundThreadDeflate = false;
477 bool bTransportOwnEncrStreamAsRaw = false;
478 // During the storing the original size of the stream can be changed
479 // TODO/LATER: get rid of this hack
481
482 bool bUseNonSeekableAccess = false;
483 uno::Reference < io::XInputStream > xStream;
484 if ( !IsPackageMember() && !m_bRawStream && !bToBeEncrypted && bToBeCompressed )
485 {
486 // the stream is not a package member, not a raw stream,
487 // it should not be encrypted and it should be compressed,
488 // in this case nonseekable access can be used
489
491 uno::Reference < io::XSeekable > xSeek ( xStream, uno::UNO_QUERY );
492
493 bUseNonSeekableAccess = ( xStream.is() && !xSeek.is() );
494 }
495
496 if ( !bUseNonSeekableAccess )
497 {
499
500 if ( !xStream.is() )
501 {
502 OSL_FAIL( "ZipPackageStream didn't have a stream associated with it, skipping!" );
503 bSuccess = false;
504 return bSuccess;
505 }
506
507 uno::Reference < io::XSeekable > xSeek ( xStream, uno::UNO_QUERY );
508 try
509 {
510 if ( xSeek.is() )
511 {
512 // If the stream is a raw one, then we should be positioned
513 // at the beginning of the actual data
514 if ( !bToBeCompressed || m_bRawStream )
515 {
516 // The raw stream can neither be encrypted nor connected
517 OSL_ENSURE( !m_bRawStream || !(bToBeCompressed || bToBeEncrypted), "The stream is already encrypted!" );
518 xSeek->seek ( m_bRawStream ? m_nMagicalHackPos : 0 );
519 ImplSetStoredData ( *pTempEntry, xStream );
520
521 // TODO/LATER: Get rid of hacks related to switching of Flag Method and Size properties!
522 }
523 else if ( bToBeEncrypted )
524 {
525 // this is the correct original size
526 pTempEntry->nSize = xSeek->getLength();
527 m_nOwnStreamOrigSize = pTempEntry->nSize;
528 }
529
530 xSeek->seek ( 0 );
531 }
532 else
533 {
534 // Okay, we don't have an xSeekable stream. This is possibly bad.
535 // check if it's one of our own streams, if it is then we know that
536 // each time we ask for it we'll get a new stream that will be
537 // at position zero...otherwise, assert and skip this stream...
538 if ( IsPackageMember() )
539 {
540 // if the password has been changed then the stream should not be package member any more
542 {
543 // Should be handled close to the raw stream handling
544 bTransportOwnEncrStreamAsRaw = true;
545 pTempEntry->nMethod = STORED;
546
547 // TODO/LATER: get rid of this situation
548 // this size should be different from the one that will be stored in manifest.xml
549 // it is used in storing algorithms and after storing the correct size will be set
550 pTempEntry->nSize = pTempEntry->nCompressedSize;
551 }
552 }
553 else
554 {
555 bSuccess = false;
556 return bSuccess;
557 }
558 }
559 }
560 catch ( uno::Exception& )
561 {
562 bSuccess = false;
563 return bSuccess;
564 }
565
566 if ( bToBeEncrypted || m_bRawStream || bTransportOwnEncrStreamAsRaw )
567 {
568 if ( bToBeEncrypted && !bTransportOwnEncrStreamAsRaw )
569 {
570 uno::Sequence < sal_Int8 > aSalt( 16 ), aVector( GetBlockSize() );
571 rtl_random_getBytes ( rRandomPool, aSalt.getArray(), 16 );
572 rtl_random_getBytes ( rRandomPool, aVector.getArray(), aVector.getLength() );
573 if ( !m_bHaveOwnKey )
574 {
575 m_aEncryptionKey = rEncryptionKey;
576 m_aStorageEncryptionKeys.realloc( 0 );
577 }
578
579 setInitialisationVector ( aVector );
580 setSalt ( aSalt );
581 setIterationCount(nPBKDF2IterationCount);
582 }
583
584 // last property is digest, which is inserted later if we didn't have
585 // a magic header
586 aPropSet.realloc(PKG_SIZE_ENCR_MNFST);
587 pPropSet = aPropSet.getArray();
588 pPropSet[PKG_MNFST_INIVECTOR].Name = "InitialisationVector";
589 pPropSet[PKG_MNFST_INIVECTOR].Value <<= m_xBaseEncryptionData->m_aInitVector;
590 pPropSet[PKG_MNFST_SALT].Name = "Salt";
591 pPropSet[PKG_MNFST_SALT].Value <<= m_xBaseEncryptionData->m_aSalt;
592 pPropSet[PKG_MNFST_ITERATION].Name = "IterationCount";
593 pPropSet[PKG_MNFST_ITERATION].Value <<= m_xBaseEncryptionData->m_nIterationCount;
594
595 // Need to store the uncompressed size in the manifest
596 OSL_ENSURE( m_nOwnStreamOrigSize >= 0, "The stream size was not correctly initialized!" );
597 pPropSet[PKG_MNFST_UCOMPSIZE].Name = "Size";
598 pPropSet[PKG_MNFST_UCOMPSIZE].Value <<= m_nOwnStreamOrigSize;
599
600 if ( m_bRawStream || bTransportOwnEncrStreamAsRaw )
601 {
603 if ( !xEncData.is() )
604 throw uno::RuntimeException();
605
606 pPropSet[PKG_MNFST_DIGEST].Name = sDigestProperty;
607 pPropSet[PKG_MNFST_DIGEST].Value <<= m_xBaseEncryptionData->m_aDigest;
608 pPropSet[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
609 pPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg;
610 pPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
611 pPropSet[PKG_MNFST_STARTALG].Value <<= xEncData->m_nStartKeyGenID;
612 pPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
613 pPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg;
614 pPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
615 pPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize;
616 }
617 }
618 }
619
620 // If the entry is already stored in the zip file in the format we
621 // want for this write...copy it raw
622 if ( !bUseNonSeekableAccess
623 && ( m_bRawStream || bTransportOwnEncrStreamAsRaw
624 || ( IsPackageMember() && !bToBeEncrypted
625 && ( ( aEntry.nMethod == DEFLATED && bToBeCompressed )
626 || ( aEntry.nMethod == STORED && !bToBeCompressed ) ) ) ) )
627 {
628 // If it's a PackageMember, then it's an unbuffered stream and we need
629 // to get a new version of it as we can't seek backwards.
630 if ( IsPackageMember() )
631 {
633 if ( !xStream.is() )
634 {
635 // Make sure that we actually _got_ a new one !
636 bSuccess = false;
637 return bSuccess;
638 }
639 }
640
641 try
642 {
643 if ( m_bRawStream )
644 xStream->skipBytes( m_nMagicalHackPos );
645
646 ZipOutputStream::setEntry(pTempEntry);
647 rZipOut.writeLOC(pTempEntry);
648 // coverity[leaked_storage] - the entry is provided to the ZipOutputStream that will delete it
649 pAutoTempEntry.release();
650
651 uno::Sequence < sal_Int8 > aSeq ( n_ConstBufferSize );
652 sal_Int32 nLength;
653
654 do
655 {
656 nLength = xStream->readBytes( aSeq, n_ConstBufferSize );
658 aSeq.realloc(nLength);
659
660 rZipOut.rawWrite(aSeq);
661 }
662 while ( nLength == n_ConstBufferSize );
663
664 rZipOut.rawCloseEntry();
665 }
666 catch ( ZipException& )
667 {
668 bSuccess = false;
669 }
670 catch ( io::IOException& )
671 {
672 bSuccess = false;
673 }
674 }
675 else
676 {
677 // This stream is definitely not a raw stream
678
679 // If nonseekable access is used the stream should be at the beginning and
680 // is useless after the storing. Thus if the storing fails the package should
681 // be thrown away ( as actually it is done currently )!
682 // To allow to reuse the package after the error, the optimization must be removed!
683
684 // If it's a PackageMember, then our previous reference held a 'raw' stream
685 // so we need to re-get it, unencrypted, uncompressed and positioned at the
686 // beginning of the stream
687 if ( IsPackageMember() )
688 {
690 if ( !xStream.is() )
691 {
692 // Make sure that we actually _got_ a new one !
693 bSuccess = false;
694 return bSuccess;
695 }
696 }
697
698 if ( bToBeCompressed )
699 {
700 pTempEntry->nMethod = DEFLATED;
701 pTempEntry->nCrc = -1;
702 pTempEntry->nCompressedSize = pTempEntry->nSize = -1;
703 }
704
705 uno::Reference< io::XSeekable > xSeek(xStream, uno::UNO_QUERY);
706 // It's not worth to deflate jpegs to save ~1% in a slow process
707 // Unfortunately, does not work for streams protected by password
708 if (xSeek.is() && msMediaType.endsWith("/jpeg") && !m_bToBeEncrypted && !m_bToBeCompressed)
709 {
710 ImplSetStoredData(*pTempEntry, xStream);
711 xSeek->seek(0);
712 }
713
714 try
715 {
716 ZipOutputStream::setEntry(pTempEntry);
717 // the entry is provided to the ZipOutputStream that will delete it
718 pAutoTempEntry.release();
719
720 if (pTempEntry->nMethod == STORED)
721 {
722 sal_Int32 nLength;
723 uno::Sequence< sal_Int8 > aSeq(n_ConstBufferSize);
724 rZipOut.writeLOC(pTempEntry, bToBeEncrypted);
725 do
726 {
727 nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
729 aSeq.realloc(nLength);
730
731 rZipOut.rawWrite(aSeq);
732 }
733 while ( nLength == n_ConstBufferSize );
734 rZipOut.rawCloseEntry(bToBeEncrypted);
735 }
736 else
737 {
738 // tdf#89236 Encrypting in a background thread does not work
739 bBackgroundThreadDeflate = !bToBeEncrypted;
740 // Do not deflate small streams using threads. XSeekable's getLength()
741 // gives the full size, XInputStream's available() may not be
742 // the full size, but it appears that at this point it usually is.
743 sal_Int64 estimatedSize = xSeek.is() ? xSeek->getLength() : xStream->available();
744
745 if (estimatedSize > 1000000)
746 {
747 // Use ThreadDeflater which will split the stream into blocks and compress
748 // them in threads, but not in background (i.e. writeStream() will block).
749 // This is suitable for large data.
750 bBackgroundThreadDeflate = false;
751 rZipOut.writeLOC(pTempEntry, bToBeEncrypted);
752 ZipOutputEntryParallel aZipEntry(rZipOut.getStream(), m_xContext, *pTempEntry, this, bToBeEncrypted);
753 aZipEntry.writeStream(xStream);
754 rZipOut.rawCloseEntry(bToBeEncrypted);
755 }
756 else if (bBackgroundThreadDeflate && estimatedSize > 100000)
757 {
758 // tdf#93553 limit to a useful amount of pending tasks. Having way too many
759 // tasks pending may use a lot of memory. Take number of available
760 // cores and allow 4-times the amount for having the queue well filled. The
761 // 2nd parameter is the time to wait between cleanups in 10th of a second.
762 // Both values may be added to the configuration settings if needed.
763 static std::size_t nAllowedTasks(comphelper::ThreadPool::getPreferredConcurrency() * 4); //TODO: overflow
765
766 // Start a new thread task deflating this zip entry
768 m_xContext, *pTempEntry, this, bToBeEncrypted);
769 rZipOut.addDeflatingThreadTask( pZipEntry,
770 pZipEntry->createTask( rZipOut.getThreadTaskTag(), xStream) );
771 }
772 else
773 {
774 bBackgroundThreadDeflate = false;
775 rZipOut.writeLOC(pTempEntry, bToBeEncrypted);
776 ZipOutputEntry aZipEntry(rZipOut.getStream(), m_xContext, *pTempEntry, this, bToBeEncrypted);
777 aZipEntry.writeStream(xStream);
778 rZipOut.rawCloseEntry(bToBeEncrypted);
779 }
780 }
781 }
782 catch ( ZipException& )
783 {
784 bSuccess = false;
785 }
786 catch ( io::IOException& )
787 {
788 bSuccess = false;
789 }
790
791 if ( bToBeEncrypted )
792 {
794 if ( !xEncData.is() )
795 throw uno::RuntimeException();
796
797 pPropSet[PKG_MNFST_DIGEST].Name = sDigestProperty;
798 pPropSet[PKG_MNFST_DIGEST].Value <<= m_xBaseEncryptionData->m_aDigest;
799 pPropSet[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
800 pPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg;
801 pPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
802 pPropSet[PKG_MNFST_STARTALG].Value <<= xEncData->m_nStartKeyGenID;
803 pPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
804 pPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg;
805 pPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
806 pPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize;
807
808 SetIsEncrypted ( true );
809 }
810 }
811
812 if (bSuccess && !bBackgroundThreadDeflate)
813 successfullyWritten(pTempEntry);
814
815 if ( aPropSet.hasElements()
816 && ( m_nFormat == embed::StorageFormats::PACKAGE || m_nFormat == embed::StorageFormats::OFOPXML ) )
817 rManList.push_back( aPropSet );
818
819 return bSuccess;
820}
821
823{
824 if ( !IsPackageMember() )
825 {
826 if ( m_xStream.is() )
827 {
828 m_xStream->closeInput();
829 m_xStream.clear();
830 m_bHasSeekable = false;
831 }
832 SetPackageMember ( true );
833 }
834
835 if ( m_bRawStream )
836 {
837 // the raw stream was integrated and now behaves
838 // as usual encrypted stream
839 SetToBeEncrypted( true );
840 }
841
842 // Then copy it back afterwards...
843 aEntry = *pEntry;
844
845 // TODO/LATER: get rid of this hack ( the encrypted stream size property is changed during saving )
846 if ( m_bIsEncrypted )
848
849 aEntry.nOffset *= -1;
850}
851
853{
854 if ( bNewValue )
855 {
859 }
861 m_nStreamMode = PACKAGE_STREAM_NOTSET; // must be reset
862}
863
864// XActiveDataSink
865void SAL_CALL ZipPackageStream::setInputStream( const uno::Reference< io::XInputStream >& aStream )
866{
867 // if seekable access is required the wrapping will be done on demand
868 m_xStream = aStream;
870 m_bHasSeekable = false;
871 SetPackageMember ( false );
872 aEntry.nTime = -1;
874}
875
876uno::Reference< io::XInputStream > ZipPackageStream::getRawData()
877{
878 try
879 {
880 if ( IsPackageMember() )
881 {
882 return m_rZipPackage.getZipFile().getRawData( aEntry, GetEncryptionData(), m_bIsEncrypted, m_rZipPackage.GetSharedMutexRef(), false/*bUseBufferedStream*/ );
883 }
884 else if ( GetOwnSeekStream().is() )
885 {
887 }
888 else
889 return uno::Reference < io::XInputStream > ();
890 }
891 catch ( ZipException & )//rException )
892 {
893 TOOLS_WARN_EXCEPTION( "package", "" );
894 return uno::Reference < io::XInputStream > ();
895 }
896 catch ( Exception & )
897 {
898 TOOLS_WARN_EXCEPTION( "package", "Exception is thrown during stream wrapping!" );
899 return uno::Reference < io::XInputStream > ();
900 }
901}
902
903uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getInputStream()
904{
905 try
906 {
907 if ( IsPackageMember() )
908 {
910 }
911 else if ( GetOwnSeekStream().is() )
912 {
914 }
915 else
916 return uno::Reference < io::XInputStream > ();
917 }
918 catch ( ZipException & )//rException )
919 {
920 TOOLS_WARN_EXCEPTION( "package", "" );
921 return uno::Reference < io::XInputStream > ();
922 }
923 catch ( const Exception & )
924 {
925 TOOLS_WARN_EXCEPTION( "package", "Exception is thrown during stream wrapping!");
926 return uno::Reference < io::XInputStream > ();
927 }
928}
929
930// XDataSinkEncrSupport
931uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream()
932{
933 // There is no stream attached to this object
935 return uno::Reference< io::XInputStream >();
936
937 // this method can not be used together with old approach
939 throw packages::zip::ZipIOException(THROW_WHERE );
940
941 if ( IsPackageMember() )
942 {
943 uno::Reference< io::XInputStream > xResult;
944 try
945 {
947 }
948 catch( const packages::WrongPasswordException& )
949 {
950 if ( m_rZipPackage.GetStartKeyGenID() == xml::crypto::DigestID::SHA1 )
951 {
952 SAL_WARN("package", "ZipPackageStream::getDataStream(): SHA1 mismatch, trying fallbacks...");
953 try
954 { // tdf#114939 try with legacy StarOffice SHA1 bug
956 return xResult;
957 }
958 catch (const packages::WrongPasswordException&)
959 {
960 /* ignore and try next... */
961 }
962
963 try
964 {
965 // rhbz#1013844 / fdo#47482 workaround for the encrypted
966 // OpenOffice.org 1.0 documents generated by Libreoffice <=
967 // 3.6 with the new encryption format and using SHA256, but
968 // missing a specified startkey of SHA256
969
970 // force SHA256 and see if that works
971 m_nImportedStartKeyAlgorithm = xml::crypto::DigestID::SHA256;
973 return xResult;
974 }
975 catch (const packages::WrongPasswordException&)
976 {
977 // if that didn't work, restore to SHA1 and trundle through the *other* earlier
978 // bug fix
979 m_nImportedStartKeyAlgorithm = xml::crypto::DigestID::SHA1;
980 }
981
982 // workaround for the encrypted documents generated with the old OOo1.x bug.
983 if ( !m_bUseWinEncoding )
984 {
986 m_bUseWinEncoding = true;
987 }
988 else
989 throw;
990 }
991 else
992 throw;
993 }
994 return xResult;
995 }
996 else if ( m_nStreamMode == PACKAGE_STREAM_RAW )
997 return ZipFile::StaticGetDataFromRawStream( m_rZipPackage.GetSharedMutexRef(), m_xContext, GetOwnSeekStream(), GetEncryptionData() );
998 else if ( GetOwnSeekStream().is() )
999 {
1001 }
1002 else
1003 return uno::Reference< io::XInputStream >();
1004}
1005
1006uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawStream()
1007{
1008 // There is no stream attached to this object
1010 return uno::Reference< io::XInputStream >();
1011
1012 // this method can not be used together with old approach
1014 throw packages::zip::ZipIOException(THROW_WHERE );
1015
1016 if ( IsPackageMember() )
1017 {
1018 if ( !m_bIsEncrypted || !GetEncryptionData().is() )
1019 throw packages::NoEncryptionException(THROW_WHERE );
1020
1021 return m_rZipPackage.getZipFile().getWrappedRawStream( aEntry, GetEncryptionData(), msMediaType, m_rZipPackage.GetSharedMutexRef() );
1022 }
1023 else if ( GetOwnSeekStream().is() )
1024 {
1026 {
1028 }
1030 return TryToGetRawFromDataStream( true );
1031 }
1032
1033 throw packages::NoEncryptionException(THROW_WHERE );
1034}
1035
1036void SAL_CALL ZipPackageStream::setDataStream( const uno::Reference< io::XInputStream >& aStream )
1037{
1038 setInputStream( aStream );
1040}
1041
1042void SAL_CALL ZipPackageStream::setRawStream( const uno::Reference< io::XInputStream >& aStream )
1043{
1044 // wrap the stream in case it is not seekable
1045 uno::Reference< io::XInputStream > xNewStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( aStream, m_xContext );
1046 uno::Reference< io::XSeekable > xSeek( xNewStream, UNO_QUERY_THROW );
1047 xSeek->seek( 0 );
1048 uno::Reference< io::XInputStream > xOldStream = m_xStream;
1049 m_xStream = xNewStream;
1050 if ( !ParsePackageRawStream() )
1051 {
1052 m_xStream = xOldStream;
1053 throw packages::NoRawFormatException(THROW_WHERE );
1054 }
1055
1056 // the raw stream MUST have seekable access
1057 m_bHasSeekable = true;
1058
1059 SetPackageMember ( false );
1060 aEntry.nTime = -1;
1062}
1063
1064uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getPlainRawStream()
1065{
1066 // There is no stream attached to this object
1068 return uno::Reference< io::XInputStream >();
1069
1070 // this method can not be used together with old approach
1072 throw packages::zip::ZipIOException(THROW_WHERE );
1073
1074 if ( IsPackageMember() )
1075 {
1077 }
1078 else if ( GetOwnSeekStream().is() )
1079 {
1081 {
1082 // the header should not be returned here
1084 }
1085 else if ( m_nStreamMode == PACKAGE_STREAM_DATA )
1086 return TryToGetRawFromDataStream( false );
1087 }
1088
1089 return uno::Reference< io::XInputStream >();
1090}
1091
1092// XPropertySet
1093void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
1094{
1095 if ( aPropertyName == "MediaType" )
1096 {
1097 if ( m_rZipPackage.getFormat() != embed::StorageFormats::PACKAGE && m_rZipPackage.getFormat() != embed::StorageFormats::OFOPXML )
1098 throw beans::PropertyVetoException(THROW_WHERE );
1099
1100 if ( !(aValue >>= msMediaType) )
1101 throw IllegalArgumentException(THROW_WHERE "MediaType must be a string!",
1102 uno::Reference< XInterface >(),
1103 2 );
1104
1105 if ( !msMediaType.isEmpty() )
1106 {
1107 if ( msMediaType.indexOf ( "text" ) != -1
1108 || msMediaType == "application/vnd.sun.star.oleobject" )
1109 m_bToBeCompressed = true;
1111 m_bToBeCompressed = false;
1112 }
1113 }
1114 else if ( aPropertyName == "Size" )
1115 {
1116 if ( !( aValue >>= aEntry.nSize ) )
1117 throw IllegalArgumentException(THROW_WHERE "Wrong type for Size property!",
1118 uno::Reference< XInterface >(),
1119 2 );
1120 }
1121 else if ( aPropertyName == "Encrypted" )
1122 {
1123 if ( m_rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
1124 throw beans::PropertyVetoException(THROW_WHERE );
1125
1126 bool bEnc = false;
1127 if ( !(aValue >>= bEnc) )
1128 throw IllegalArgumentException(THROW_WHERE "Wrong type for Encrypted property!",
1129 uno::Reference< XInterface >(),
1130 2 );
1131
1132 // In case of new raw stream, the stream must not be encrypted on storing
1133 if ( bEnc && m_nStreamMode == PACKAGE_STREAM_RAW )
1134 throw IllegalArgumentException(THROW_WHERE "Raw stream can not be encrypted on storing",
1135 uno::Reference< XInterface >(),
1136 2 );
1137
1138 m_bToBeEncrypted = bEnc;
1141
1142 }
1143 else if ( aPropertyName == ENCRYPTION_KEY_PROPERTY )
1144 {
1145 if ( m_rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
1146 throw beans::PropertyVetoException(THROW_WHERE );
1147
1148 uno::Sequence< sal_Int8 > aNewKey;
1149
1150 if ( !( aValue >>= aNewKey ) )
1151 {
1152 OUString sTempString;
1153 if ( !(aValue >>= sTempString) )
1154 throw IllegalArgumentException(THROW_WHERE "Wrong type for EncryptionKey property!",
1155 uno::Reference< XInterface >(),
1156 2 );
1157
1158 sal_Int32 nPathLength = sTempString.getLength();
1159 Sequence < sal_Int8 > aSequence ( nPathLength );
1160 sal_Int8 *pArray = aSequence.getArray();
1161 const sal_Unicode *pChar = sTempString.getStr();
1162 for ( sal_Int32 i = 0; i < nPathLength; i++ )
1163 pArray[i] = static_cast < sal_Int8 > ( pChar[i] );
1164 aNewKey = aSequence;
1165 }
1166
1167 if ( aNewKey.hasElements() )
1168 {
1169 if ( !m_xBaseEncryptionData.is() )
1171
1172 m_aEncryptionKey = aNewKey;
1173 // In case of new raw stream, the stream must not be encrypted on storing
1174 m_bHaveOwnKey = true;
1176 m_bToBeEncrypted = true;
1177 }
1178 else
1179 {
1180 m_bHaveOwnKey = false;
1181 m_aEncryptionKey.realloc( 0 );
1182 }
1183
1184 m_aStorageEncryptionKeys.realloc( 0 );
1185 }
1186 else if ( aPropertyName == STORAGE_ENCRYPTION_KEYS_PROPERTY )
1187 {
1188 if ( m_rZipPackage.getFormat() != embed::StorageFormats::PACKAGE )
1189 throw beans::PropertyVetoException(THROW_WHERE );
1190
1191 uno::Sequence< beans::NamedValue > aKeys;
1192 if ( !( aValue >>= aKeys ) )
1193 {
1194 throw IllegalArgumentException(THROW_WHERE "Wrong type for StorageEncryptionKeys property!",
1195 uno::Reference< XInterface >(),
1196 2 );
1197 }
1198
1199 if ( aKeys.hasElements() )
1200 {
1201 if ( !m_xBaseEncryptionData.is() )
1203
1205
1206 // In case of new raw stream, the stream must not be encrypted on storing
1207 m_bHaveOwnKey = true;
1209 m_bToBeEncrypted = true;
1210 }
1211 else
1212 {
1213 m_bHaveOwnKey = false;
1214 m_aStorageEncryptionKeys.realloc( 0 );
1215 }
1216
1217 m_aEncryptionKey.realloc( 0 );
1218 }
1219 else if ( aPropertyName == "Compressed" )
1220 {
1221 bool bCompr = false;
1222
1223 if ( !(aValue >>= bCompr) )
1224 throw IllegalArgumentException(THROW_WHERE "Wrong type for Compressed property!",
1225 uno::Reference< XInterface >(),
1226 2 );
1227
1228 // In case of new raw stream, the stream must not be encrypted on storing
1229 if ( bCompr && m_nStreamMode == PACKAGE_STREAM_RAW )
1230 throw IllegalArgumentException(THROW_WHERE "Raw stream can not be encrypted on storing",
1231 uno::Reference< XInterface >(),
1232 2 );
1233
1234 m_bToBeCompressed = bCompr;
1236 }
1237 else
1238 throw beans::UnknownPropertyException(aPropertyName);
1239}
1240
1241Any SAL_CALL ZipPackageStream::getPropertyValue( const OUString& PropertyName )
1242{
1243 if ( PropertyName == "MediaType" )
1244 {
1245 return Any(msMediaType);
1246 }
1247 else if ( PropertyName == "Size" )
1248 {
1249 return Any(aEntry.nSize);
1250 }
1251 else if ( PropertyName == "Encrypted" )
1252 {
1254 }
1255 else if ( PropertyName == "WasEncrypted" )
1256 {
1257 return Any(m_bIsEncrypted);
1258 }
1259 else if ( PropertyName == "Compressed" )
1260 {
1261 return Any(m_bToBeCompressed);
1262 }
1263 else if ( PropertyName == ENCRYPTION_KEY_PROPERTY )
1264 {
1265 return Any(m_aEncryptionKey);
1266 }
1267 else if ( PropertyName == STORAGE_ENCRYPTION_KEYS_PROPERTY )
1268 {
1270 }
1271 else
1272 throw beans::UnknownPropertyException(PropertyName);
1273}
1274
1275void ZipPackageStream::setSize ( const sal_Int64 nNewSize )
1276{
1277 if ( aEntry.nCompressedSize != nNewSize )
1278 aEntry.nMethod = DEFLATED;
1279 aEntry.nSize = nNewSize;
1280}
1282{
1283 return "ZipPackageStream";
1284}
1285
1287{
1288 return { "com.sun.star.packages.PackageStream" };
1289}
1290
1291sal_Bool SAL_CALL ZipPackageStream::supportsService( OUString const & rServiceName )
1292{
1293 return cppu::supportsService(this, rServiceName);
1294}
1295
1296/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const sal_Int32 n_ConstHeaderSize
const sal_uInt32 n_ConstHeader
Reference< XComponentContext > m_xContext
#define PKG_MNFST_SALT
#define PKG_MNFST_DERKEYSIZE
#define PKG_MNFST_DIGEST
#define PKG_MNFST_DIGESTALG
#define PKG_MNFST_UCOMPSIZE
#define PKG_SIZE_NOENCR_MNFST
#define PKG_MNFST_ITERATION
#define PKG_MNFST_MEDIATYPE
#define PKG_MNFST_STARTALG
#define PKG_MNFST_ENCALG
constexpr OUStringLiteral STORAGE_ENCRYPTION_KEYS_PROPERTY
#define PKG_MNFST_VERSION
#define PKG_SIZE_ENCR_MNFST
const sal_Int32 n_ConstBufferSize
#define PKG_MNFST_FULLPATH
#define PKG_MNFST_INIVECTOR
constexpr OUStringLiteral ENCRYPTION_KEY_PROPERTY
Reference< XInputStream > xStream
void * rtlRandomPool
#define THROW_WHERE
static void ImplSetStoredData(ZipEntry &rEntry, uno::Reference< io::XInputStream > const &rStream)
#define PACKAGE_STREAM_PACKAGEMEMBER
#define PACKAGE_STREAM_RAW
#define PACKAGE_STREAM_NOTSET
#define PACKAGE_STREAM_DETECT
#define PACKAGE_STREAM_DATA
Definition: CRC32.hxx:29
sal_Int32 getValue() const
Definition: CRC32.cxx:39
sal_Int64 updateStream(css::uno::Reference< css::io::XInputStream > const &xStream)
Definition: CRC32.cxx:56
std::unique_ptr< comphelper::ThreadTask > createTask(const std::shared_ptr< comphelper::ThreadTaskTag > &pTag, const css::uno::Reference< css::io::XInputStream > &xInStream)
void writeStream(const css::uno::Reference< css::io::XInputStream > &xInStream) override
void writeStream(const css::uno::Reference< css::io::XInputStream > &xInStream) override
void writeLOC(ZipEntry *pEntry, bool bEncrypt=false)
void rawCloseEntry(bool bEncrypt=false)
const css::uno::Reference< css::io::XOutputStream > & getStream() const
void rawWrite(const css::uno::Sequence< sal_Int8 > &rBuffer)
const std::shared_ptr< comphelper::ThreadTaskTag > & getThreadTaskTag() const
static void setEntry(ZipEntry *pEntry)
void addDeflatingThreadTask(ZipOutputEntryInThread *pEntry, std::unique_ptr< comphelper::ThreadTask > pThreadTask)
void reduceScheduledThreadTasksToGivenNumberOrLess(std::size_t nThreadTasks)
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getPlainRawStream() override
sal_Int32 m_nImportedChecksumAlgorithm
sal_Int32 GetBlockSize() const
void successfullyWritten(ZipEntry const *pEntry)
::rtl::Reference< BaseEncryptionData > m_xBaseEncryptionData
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getDataStream() override
css::uno::Reference< css::io::XInputStream > GetRawEncrStreamNoHeaderCopy()
css::uno::Sequence< sal_Int8 > m_aEncryptionKey
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getRawStream() override
css::uno::Reference< css::io::XInputStream > getRawData()
get raw data using unbuffered stream
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getInputStream() override
void SetPackageMember(bool bNewValue)
css::uno::Reference< css::io::XInputStream > TryToGetRawFromDataStream(bool bAddHeaderForEncr)
virtual void SAL_CALL setInputStream(const css::uno::Reference< css::io::XInputStream > &aStream) override
sal_Int64 m_nOwnStreamOrigSize
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
sal_Int32 m_nImportedStartKeyAlgorithm
ZipPackageStream(ZipPackage &rNewPackage, const css::uno::Reference< css::uno::XComponentContext > &xContext, sal_Int32 nFormat, bool bAllowRemoveOnInsert)
::rtl::Reference< EncryptionData > GetEncryptionData(Bugs bugs=Bugs::None)
void SetToBeEncrypted(bool bNewValue)
ZipPackage & m_rZipPackage
sal_uInt32 m_nMagicalHackPos
void SetIsEncrypted(bool bNewValue)
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
sal_Int32 m_nImportedDerivedKeySize
virtual void SAL_CALL setDataStream(const css::uno::Reference< css::io::XInputStream > &aStream) override
sal_Int32 GetStartKeyGenID() const
bool IsPackageMember() const
virtual bool saveChild(const OUString &rPath, std::vector< css::uno::Sequence< css::beans::PropertyValue > > &rManList, ZipOutputStream &rZipOut, const css::uno::Sequence< sal_Int8 > &rEncryptionKey, sal_Int32 nPBKDF2IterationCount, const rtlRandomPool &rRandomPool) override
sal_Int32 GetEncryptionAlgorithm() const
virtual ~ZipPackageStream() override
void setInitialisationVector(const css::uno::Sequence< sal_Int8 > &rNewVector)
void setSalt(const css::uno::Sequence< sal_Int8 > &rNewSalt)
virtual OUString SAL_CALL getImplementationName() override
css::uno::Sequence< css::beans::NamedValue > m_aStorageEncryptionKeys
css::uno::Reference< css::io::XInputStream > const & GetOwnSeekStream()
Check that m_xStream implements io::XSeekable and return it.
sal_uInt32 m_nMagicalHackSize
sal_Int32 m_nImportedEncryptionAlgorithm
void setSize(const sal_Int64 nNewSize)
virtual void SAL_CALL setRawStream(const css::uno::Reference< css::io::XInputStream > &aStream) override
css::uno::Reference< css::io::XInputStream > m_xStream
void setZipEntryOnLoading(const ZipEntry &rInEntry)
void setIterationCount(const sal_Int32 nNewCount)
css::uno::Sequence< sal_Int8 > GetEncryptionKey(Bugs bugs=Bugs::None)
ZipFile & getZipFile()
Definition: ZipPackage.hxx:121
sal_Int32 getFormat() const
Definition: ZipPackage.hxx:122
rtl::Reference< comphelper::RefCountedMutex > & GetSharedMutexRef()
Definition: ZipPackage.hxx:129
sal_Int32 GetStartKeyGenID() const
Definition: ZipPackage.hxx:124
sal_Int32 GetDefaultDerivedKeySize() const
Definition: ZipPackage.hxx:127
sal_Int32 GetChecksumAlgID() const
Definition: ZipPackage.hxx:126
sal_Int32 GetEncAlgID() const
Definition: ZipPackage.hxx:125
css::uno::Sequence< sal_Int8 > GetEncryptionKey()
static css::uno::Reference< css::io::XInputStream > CheckSeekableCanWrap(const css::uno::Reference< css::io::XInputStream > &xInStream, const css::uno::Reference< css::uno::XComponentContext > &rxContext)
static void CopyInputToOutput(const css::uno::Reference< css::io::XInputStream > &xInput, const css::uno::Reference< css::io::XOutputStream > &xOutput)
static std::size_t getPreferredConcurrency()
#define TOOLS_WARN_EXCEPTION(area, stream)
float u
Sequence< sal_Int8 > aSeq
#define SAL_WARN(area, stream)
@ Exception
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
sal_uInt16 const m_nFormat
constexpr OUStringLiteral PACKAGE_ENCRYPTIONDATA_SHA1UTF8
constexpr OUStringLiteral PACKAGE_ENCRYPTIONDATA_SHA1CORRECT
constexpr OUStringLiteral PACKAGE_ENCRYPTIONDATA_SHA1MS1252
constexpr OUStringLiteral PACKAGE_ENCRYPTIONDATA_SHA256UTF8
sal_Int64 nCompressedSize
Definition: ZipEntry.hxx:31
sal_Int16 nVersion
Definition: ZipEntry.hxx:26
sal_Int64 nOffset
Definition: ZipEntry.hxx:33
sal_Int32 nCrc
Definition: ZipEntry.hxx:30
sal_Int64 nSize
Definition: ZipEntry.hxx:32
sal_Int32 nTime
Definition: ZipEntry.hxx:29
sal_Int16 nExtraLen
Definition: ZipEntry.hxx:35
OUString sPath
Definition: ZipEntry.hxx:36
sal_Int16 nFlag
Definition: ZipEntry.hxx:27
sal_Int16 nMethod
Definition: ZipEntry.hxx:28
sal_Int16 nPathLen
Definition: ZipEntry.hxx:34
unsigned char sal_Bool
sal_uInt16 sal_Unicode
signed char sal_Int8
const char * pChar
sal_Int32 nLength