LibreOffice Module sc (master)  1
xistream.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 
22 #include <osl/thread.h>
23 #include <osl/diagnose.h>
24 #include <sal/log.hxx>
25 #include <tools/solar.h>
26 #include <ftools.hxx>
27 #include <xistream.hxx>
28 #include <xlstring.hxx>
29 #include <xiroot.hxx>
30 
31 #include <vector>
32 #include <memory>
33 
34 using namespace ::com::sun::star;
35 
36 // Decryption
38  mnError( EXC_ENCR_ERROR_UNSUPP_CRYPT ),
39  mnOldPos( STREAM_SEEK_TO_END ),
40  mnRecSize( 0 )
41 {
42 }
43 
45  ::comphelper::IDocPasswordVerifier(),
46  mnError( rSrc.mnError ),
47  mnOldPos( STREAM_SEEK_TO_END ),
48  mnRecSize( 0 )
49 {
50 }
51 
53 {
54 }
55 
57 {
58  XclImpDecrypterRef xNewDecr;
59  if( IsValid() )
60  xNewDecr.reset( OnClone() );
61  return xNewDecr;
62 }
63 
64 ::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyPassword( const OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData )
65 {
66  o_rEncryptionData = OnVerifyPassword( rPassword );
67  mnError = o_rEncryptionData.hasElements() ? ERRCODE_NONE : ERRCODE_ABORT;
68  return o_rEncryptionData.hasElements() ? ::comphelper::DocPasswordVerifierResult::OK : ::comphelper::DocPasswordVerifierResult::WrongPassword;
69 }
70 
71 ::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
72 {
73  bool bValid = OnVerifyEncryptionData( rEncryptionData );
74  mnError = bValid ? ERRCODE_NONE : ERRCODE_ABORT;
75  return bValid ? ::comphelper::DocPasswordVerifierResult::OK : ::comphelper::DocPasswordVerifierResult::WrongPassword;
76 }
77 
78 void XclImpDecrypter::Update( const SvStream& rStrm, sal_uInt16 nRecSize )
79 {
80  if( IsValid() )
81  {
82  sal_uInt64 const nNewPos = rStrm.Tell();
83  if( (mnOldPos != nNewPos) || (mnRecSize != nRecSize) )
84  {
85  OnUpdate( mnOldPos, nNewPos, nRecSize );
86  mnOldPos = nNewPos;
87  mnRecSize = nRecSize;
88  }
89  }
90 }
91 
92 sal_uInt16 XclImpDecrypter::Read( SvStream& rStrm, void* pData, sal_uInt16 nBytes )
93 {
94  sal_uInt16 nRet = 0;
95  if( pData && nBytes )
96  {
97  if( IsValid() )
98  {
99  Update( rStrm, mnRecSize );
100  nRet = OnRead( rStrm, static_cast< sal_uInt8* >( pData ), nBytes );
101  mnOldPos = rStrm.Tell();
102  }
103  else
104  nRet = static_cast<sal_uInt16>(rStrm.ReadBytes(pData, nBytes));
105  }
106  return nRet;
107 }
108 
109 XclImpBiff5Decrypter::XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash ) :
110  mnKey( nKey ),
111  mnHash( nHash )
112 {
113 }
114 
116  XclImpDecrypter( rSrc ),
117  maEncryptionData( rSrc.maEncryptionData ),
118  mnKey( rSrc.mnKey ),
119  mnHash( rSrc.mnHash )
120 {
121  if( IsValid() )
123 }
124 
126 {
127  return new XclImpBiff5Decrypter( *this );
128 }
129 
130 uno::Sequence< beans::NamedValue > XclImpBiff5Decrypter::OnVerifyPassword( const OUString& rPassword )
131 {
132  maEncryptionData.realloc( 0 );
133 
134  /* Convert password to a byte string. TODO: this needs some fine tuning
135  according to the spec... */
136  OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() );
137  sal_Int32 nLen = aBytePassword.getLength();
138  if( (0 < nLen) && (nLen < 16) )
139  {
140  // init codec
141  maCodec.InitKey( reinterpret_cast<sal_uInt8 const *>(aBytePassword.getStr()) );
142 
143  if ( maCodec.VerifyKey( mnKey, mnHash ) )
144  {
146 
147  // since the export uses Std97 encryption always we have to request it here
148  ::std::vector< sal_uInt16 > aPassVect( 16 );
149  sal_Int32 nInd = 0;
150  std::for_each(aPassVect.begin(), aPassVect.begin() + nLen,
151  [&rPassword, &nInd](sal_uInt16& rPass) {
152  rPass = static_cast< sal_uInt16 >( rPassword[nInd] );
153  ++nInd;
154  });
155 
156  uno::Sequence< sal_Int8 > aDocId = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 );
157  OSL_ENSURE( aDocId.getLength() == 16, "Unexpected length of the sequence!" );
158 
159  ::msfilter::MSCodec_Std97 aCodec97;
160  aCodec97.InitKey(aPassVect.data(), reinterpret_cast<sal_uInt8 const *>(aDocId.getConstArray()));
161 
162  // merge the EncryptionData, there should be no conflicts
164  aEncryptionHash.update( ::comphelper::SequenceAsHashMap( aCodec97.GetEncryptionData() ) );
165  aEncryptionHash >> maEncryptionData;
166  }
167  }
168 
169  return maEncryptionData;
170 }
171 
172 bool XclImpBiff5Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
173 {
174  maEncryptionData.realloc( 0 );
175 
176  if( rEncryptionData.hasElements() )
177  {
178  // init codec
179  maCodec.InitCodec( rEncryptionData );
180 
181  if ( maCodec.VerifyKey( mnKey, mnHash ) )
182  maEncryptionData = rEncryptionData;
183  }
184 
185  return maEncryptionData.hasElements();
186 }
187 
188 void XclImpBiff5Decrypter::OnUpdate( std::size_t /*nOldStrmPos*/, std::size_t nNewStrmPos, sal_uInt16 nRecSize )
189 {
191  maCodec.Skip( (nNewStrmPos + nRecSize) & 0x0F );
192 }
193 
194 sal_uInt16 XclImpBiff5Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes )
195 {
196  sal_uInt16 nRet = static_cast<sal_uInt16>(rStrm.ReadBytes(pnData, nBytes));
197  maCodec.Decode( pnData, nRet );
198  return nRet;
199 }
200 
201 XclImpBiff8Decrypter::XclImpBiff8Decrypter(const std::vector<sal_uInt8>& rSalt,
202  const std::vector<sal_uInt8>& rVerifier,
203  const std::vector<sal_uInt8>& rVerifierHash)
204  : maSalt(rSalt)
205  , maVerifier(rVerifier)
206  , maVerifierHash(rVerifierHash)
207  , mpCodec(nullptr)
208 {
209 }
210 
212  : XclImpDecrypter(rSrc)
213  , maEncryptionData(rSrc.maEncryptionData)
214  , maSalt(rSrc.maSalt)
215  , maVerifier(rSrc.maVerifier)
216  , maVerifierHash(rSrc.maVerifierHash)
217  , mpCodec(nullptr)
218 {
219 }
220 
222  : XclImpBiff8Decrypter(rSrc)
223 {
224  mpCodec = &maCodec;
225  if (IsValid())
227 }
228 
230 {
231  return new XclImpBiff8StdDecrypter(*this);
232 }
233 
235  : XclImpBiff8Decrypter(rSrc)
236 {
237  mpCodec = &maCodec;
238  if (IsValid())
240 }
241 
243 {
244  return new XclImpBiff8CryptoAPIDecrypter(*this);
245 }
246 
247 uno::Sequence< beans::NamedValue > XclImpBiff8Decrypter::OnVerifyPassword( const OUString& rPassword )
248 {
249  maEncryptionData.realloc( 0 );
250 
251  sal_Int32 nLen = rPassword.getLength();
252  if( (0 < nLen) && (nLen < 16) )
253  {
254  // copy string to sal_uInt16 array
255  ::std::vector< sal_uInt16 > aPassVect( 16 );
256  const sal_Unicode* pcChar = rPassword.getStr();
257  std::for_each(aPassVect.begin(), aPassVect.begin() + nLen,
258  [&pcChar](sal_uInt16& rPass) {
259  rPass = static_cast< sal_uInt16 >( *pcChar );
260  ++pcChar;
261  });
262 
263  // init codec
264  mpCodec->InitKey(aPassVect.data(), maSalt.data());
265  if (mpCodec->VerifyKey(maVerifier.data(), maVerifierHash.data()))
267  }
268 
269  return maEncryptionData;
270 }
271 
272 bool XclImpBiff8Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
273 {
274  maEncryptionData.realloc( 0 );
275 
276  if( rEncryptionData.hasElements() )
277  {
278  // init codec
279  mpCodec->InitCodec( rEncryptionData );
280 
281  if (mpCodec->VerifyKey(maVerifier.data(), maVerifierHash.data()))
282  maEncryptionData = rEncryptionData;
283  }
284 
285  return maEncryptionData.hasElements();
286 }
287 
288 void XclImpBiff8Decrypter::OnUpdate( std::size_t nOldStrmPos, std::size_t nNewStrmPos, sal_uInt16 /*nRecSize*/ )
289 {
290  if( nNewStrmPos == nOldStrmPos )
291  return;
292 
293  sal_uInt32 nOldBlock = GetBlock( nOldStrmPos );
294  sal_uInt16 nOldOffset = GetOffset( nOldStrmPos );
295 
296  sal_uInt32 nNewBlock = GetBlock( nNewStrmPos );
297  sal_uInt16 nNewOffset = GetOffset( nNewStrmPos );
298 
299  /* Rekey cipher, if block changed or if previous offset in same block. */
300  if( (nNewBlock != nOldBlock) || (nNewOffset < nOldOffset) )
301  {
302  mpCodec->InitCipher( nNewBlock );
303  nOldOffset = 0; // reset nOldOffset for next if() statement
304  }
305 
306  /* Seek to correct offset. */
307  if( nNewOffset > nOldOffset )
308  mpCodec->Skip( nNewOffset - nOldOffset );
309 }
310 
311 sal_uInt16 XclImpBiff8Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes )
312 {
313  sal_uInt16 nRet = 0;
314 
315  sal_uInt8* pnCurrData = pnData;
316  sal_uInt16 nBytesLeft = nBytes;
317  while( nBytesLeft )
318  {
319  sal_uInt16 nBlockLeft = EXC_ENCR_BLOCKSIZE - GetOffset( rStrm.Tell() );
320  sal_uInt16 nDecBytes = ::std::min< sal_uInt16 >( nBytesLeft, nBlockLeft );
321 
322  // read the block from stream
323  nRet = nRet + static_cast<sal_uInt16>(rStrm.ReadBytes(pnCurrData, nDecBytes));
324  // decode the block inplace
325  mpCodec->Decode( pnCurrData, nDecBytes, pnCurrData, nDecBytes );
326  if( GetOffset( rStrm.Tell() ) == 0 )
327  mpCodec->InitCipher( GetBlock( rStrm.Tell() ) );
328 
329  pnCurrData += nDecBytes;
330  nBytesLeft = nBytesLeft - nDecBytes;
331  }
332 
333  return nRet;
334 }
335 
336 sal_uInt32 XclImpBiff8Decrypter::GetBlock( std::size_t nStrmPos )
337 {
338  return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE );
339 }
340 
341 sal_uInt16 XclImpBiff8Decrypter::GetOffset( std::size_t nStrmPos )
342 {
343  return static_cast< sal_uInt16 >( nStrmPos % EXC_ENCR_BLOCKSIZE );
344 }
345 
346 // Stream
348  mnPos( STREAM_SEEK_TO_BEGIN ),
349  mnNextPos( STREAM_SEEK_TO_BEGIN ),
350  mnCurrSize( 0 ),
351  mnRawRecId( EXC_ID_UNKNOWN ),
352  mnRawRecSize( 0 ),
353  mnRawRecLeft( 0 ),
354  mbValid( false )
355 {
356 }
357 
359  const SvStream& rStrm, std::size_t nNextPos, std::size_t nCurrSize,
360  sal_uInt16 nRawRecId, sal_uInt16 nRawRecSize, sal_uInt16 nRawRecLeft,
361  bool bValid )
362 {
363  mnPos = rStrm.Tell();
364  mnNextPos = nNextPos;
365  mnCurrSize = nCurrSize;
366  mnRawRecId = nRawRecId;
367  mnRawRecSize = nRawRecSize;
368  mnRawRecLeft = nRawRecLeft;
369  mbValid = bValid;
370 }
371 
373  SvStream& rStrm, std::size_t& rnNextPos, std::size_t& rnCurrSize,
374  sal_uInt16& rnRawRecId, sal_uInt16& rnRawRecSize, sal_uInt16& rnRawRecLeft,
375  bool& rbValid ) const
376 {
377  rStrm.Seek( mnPos );
378  rnNextPos = mnNextPos;
379  rnCurrSize = mnCurrSize;
380  rnRawRecId = mnRawRecId;
381  rnRawRecSize = mnRawRecSize;
382  rnRawRecLeft = mnRawRecLeft;
383  rbValid = mbValid;
384 }
385 
387 {
388  XclBiff eBiff = EXC_BIFF_UNKNOWN;
389 
390  rStrm.Seek( STREAM_SEEK_TO_BEGIN );
391  try
392  {
393  sal_uInt16 nBofId, nBofSize;
394  rStrm.ReadUInt16( nBofId ).ReadUInt16( nBofSize );
395 
396  if( (4 <= nBofSize) && (nBofSize <= 16) ) switch( nBofId )
397  {
398  case EXC_ID2_BOF:
399  eBiff = EXC_BIFF2;
400  break;
401  case EXC_ID3_BOF:
402  eBiff = EXC_BIFF3;
403  break;
404  case EXC_ID4_BOF:
405  eBiff = EXC_BIFF4;
406  break;
407  case EXC_ID5_BOF:
408  {
409  sal_uInt16 nVersion;
410  rStrm.ReadUInt16( nVersion );
411  // #i23425# #i44031# #i62752# there are some *really* broken documents out there...
412  switch( nVersion & 0xFF00 )
413  {
414  case 0: eBiff = EXC_BIFF5; break; // #i44031# #i62752#
415  case EXC_BOF_BIFF2: eBiff = EXC_BIFF2; break;
416  case EXC_BOF_BIFF3: eBiff = EXC_BIFF3; break;
417  case EXC_BOF_BIFF4: eBiff = EXC_BIFF4; break;
418  case EXC_BOF_BIFF5: eBiff = EXC_BIFF5; break;
419  case EXC_BOF_BIFF8: eBiff = EXC_BIFF8; break;
420  default: SAL_WARN("sc", "XclImpStream::DetectBiffVersion - unknown BIFF version: 0x" << std::hex << nVersion );
421  }
422  }
423  break;
424  }
425  }
426  catch (const SvStreamEOFException&)
427  {
428  SAL_WARN("sc", "EOF");
429  }
430 
431  return eBiff;
432 }
433 
434 XclImpStream::XclImpStream( SvStream& rInStrm, const XclImpRoot& rRoot ) :
435  mrStrm( rInStrm ),
436  mrRoot( rRoot ),
437  mnGlobRecId( EXC_ID_UNKNOWN ),
438  mbGlobValidRec( false ),
439  mbHasGlobPos( false ),
440  mnNextRecPos( STREAM_SEEK_TO_BEGIN ),
441  mnCurrRecSize( 0 ),
442  mnComplRecSize( 0 ),
443  mbHasComplRec( false ),
444  mnRecId( EXC_ID_UNKNOWN ),
445  mnAltContId( EXC_ID_UNKNOWN ),
446  mnRawRecId( EXC_ID_UNKNOWN ),
447  mnRawRecSize( 0 ),
448  mnRawRecLeft( 0 ),
449  mcNulSubst( '?' ),
450  mbCont( true ),
451  mbUseDecr( false ),
452  mbValidRec( false ),
453  mbValid( false )
454 {
457 }
458 
460 {
461 }
462 
464 {
465  maPosStack.clear();
466 
467  /* #i4266# Counter to ignore zero records (id==len==0) (i.e. the application
468  "Crystal Report" writes zero records between other records) */
469  std::size_t nZeroRecCount = 5;
470  bool bIsZeroRec = false;
471 
472  do
473  {
475  bIsZeroRec = (mnRawRecId == 0) && (mnRawRecSize == 0);
476  if( bIsZeroRec ) --nZeroRecCount;
478  }
479  while( mbValidRec && ((mbCont && IsContinueId( mnRawRecId )) || (bIsZeroRec && nZeroRecCount)) );
480 
481  mbValidRec = mbValidRec && !bIsZeroRec;
483  SetupRecord();
484 
485  return mbValidRec;
486 }
487 
488 bool XclImpStream::StartNextRecord( std::size_t nNextRecPos )
489 {
490  mnNextRecPos = nNextRecPos;
491  return StartNextRecord();
492 }
493 
494 void XclImpStream::ResetRecord( bool bContLookup, sal_uInt16 nAltContId )
495 {
496  if( mbValidRec )
497  {
498  maPosStack.clear();
501  mbHasComplRec = !bContLookup;
502  mbCont = bContLookup;
503  mnAltContId = nAltContId;
505  }
506 }
507 
509 {
511  mbValid = mbValidRec = false;
512 }
513 
515 {
516  mxDecrypter = xDecrypter;
518  SetupDecrypter();
519 }
520 
522 {
523  XclImpDecrypterRef xNewDecr;
524  if( rStrm.mxDecrypter )
525  xNewDecr = rStrm.mxDecrypter->Clone();
526  SetDecrypter( xNewDecr );
527 }
528 
529 void XclImpStream::EnableDecryption( bool bEnable )
530 {
531  mbUseDecr = bEnable && mxDecrypter && mxDecrypter->IsValid();
532 }
533 
535 {
536  maPosStack.emplace_back( );
537  StorePosition( maPosStack.back() );
538 }
539 
541 {
542  OSL_ENSURE( !maPosStack.empty(), "XclImpStream::PopPosition - stack empty" );
543  if( !maPosStack.empty() )
544  {
545  RestorePosition( maPosStack.back() );
546  maPosStack.pop_back();
547  }
548 }
549 
551 {
555  mbHasGlobPos = true;
556 }
557 
559 {
560  OSL_ENSURE( mbHasGlobPos, "XclImpStream::SeekGlobalPosition - no position stored" );
561  if( mbHasGlobPos )
562  {
568  }
569 }
570 
571 std::size_t XclImpStream::GetRecPos() const
572 {
574 }
575 
577 {
578  if( !mbHasComplRec )
579  {
580  PushPosition();
581  while( JumpToNextContinue() ) ; // JumpToNextContinue() adds up mnCurrRecSize
583  mbHasComplRec = true;
584  PopPosition();
585  }
586  return mnComplRecSize;
587 }
588 
590 {
591  return mbValid ? (GetRecSize() - GetRecPos()) : 0;
592 }
593 
595 {
596  sal_uInt16 nRecId = EXC_ID_UNKNOWN;
597  if( mbValidRec )
598  {
599  PushPosition();
600  while( JumpToNextContinue() ) ; // skip following CONTINUE records
601  if( mnNextRecPos < mnStreamSize )
602  {
604  mrStrm.ReadUInt16( nRecId );
605  }
606  PopPosition();
607  }
608  return nRecId;
609 }
610 
611 sal_uInt16 XclImpStream::PeekRecId( std::size_t nPos )
612 {
613  sal_uInt16 nRecId = EXC_ID_UNKNOWN;
614  if (mbValidRec && nPos < mnStreamSize)
615  {
616  sal_uInt64 const nCurPos = mrStrm.Tell();
617  mrStrm.Seek(nPos);
618  mrStrm.ReadUInt16( nRecId );
619  mrStrm.Seek(nCurPos);
620  }
621  return nRecId;
622 }
623 
625 {
626  sal_uInt8 nValue = 0;
627  if( EnsureRawReadSize( 1 ) )
628  {
629  if( mbUseDecr )
630  mxDecrypter->Read( mrStrm, &nValue, 1 );
631  else
632  mrStrm.ReadUChar( nValue );
633  --mnRawRecLeft;
634  }
635  return nValue;
636 }
637 
639 {
640  sal_Int16 nValue = 0;
641  if( EnsureRawReadSize( 2 ) )
642  {
643  if( mbUseDecr )
644  {
645  SVBT16 pnBuffer;
646  mxDecrypter->Read( mrStrm, pnBuffer, 2 );
647  nValue = static_cast< sal_Int16 >( SVBT16ToUInt16( pnBuffer ) );
648  }
649  else
650  mrStrm.ReadInt16( nValue );
651  mnRawRecLeft -= 2;
652  }
653  return nValue;
654 }
655 
657 {
658  sal_uInt16 nValue = 0;
659  if( EnsureRawReadSize( 2 ) )
660  {
661  if( mbUseDecr )
662  {
663  SVBT16 pnBuffer;
664  mxDecrypter->Read( mrStrm, pnBuffer, 2 );
665  nValue = SVBT16ToUInt16( pnBuffer );
666  }
667  else
668  mrStrm.ReadUInt16( nValue );
669  mnRawRecLeft -= 2;
670  }
671  return nValue;
672 }
673 
675 {
676  sal_Int32 nValue = 0;
677  if( EnsureRawReadSize( 4 ) )
678  {
679  if( mbUseDecr )
680  {
681  SVBT32 pnBuffer;
682  mxDecrypter->Read( mrStrm, pnBuffer, 4 );
683  nValue = static_cast< sal_Int32 >( SVBT32ToUInt32( pnBuffer ) );
684  }
685  else
686  mrStrm.ReadInt32( nValue );
687  mnRawRecLeft -= 4;
688  }
689  return nValue;
690 }
691 
693 {
694  sal_uInt32 nValue = 0;
695  if( EnsureRawReadSize( 4 ) )
696  {
697  if( mbUseDecr )
698  {
699  SVBT32 pnBuffer;
700  mxDecrypter->Read( mrStrm, pnBuffer, 4 );
701  nValue = SVBT32ToUInt32( pnBuffer );
702  }
703  else
704  mrStrm.ReadUInt32( nValue );
705  mnRawRecLeft -= 4;
706  }
707  return nValue;
708 }
709 
711 {
712  double nValue = 0;
713  if( EnsureRawReadSize( 8 ) )
714  {
715  if( mbUseDecr )
716  {
717  SVBT64 pnBuffer;
718  mxDecrypter->Read( mrStrm, pnBuffer, 8 );
719  nValue = SVBT64ToDouble( pnBuffer );
720  }
721  else
722  mrStrm.ReadDouble( nValue );
723  mnRawRecLeft -= 8;
724  }
725  return nValue;
726 }
727 
728 std::size_t XclImpStream::Read( void* pData, std::size_t nBytes )
729 {
730  std::size_t nRet = 0;
731  if( mbValid && pData && (nBytes > 0) )
732  {
733  sal_uInt8* pnBuffer = static_cast< sal_uInt8* >( pData );
734  std::size_t nBytesLeft = nBytes;
735 
736  while( mbValid && (nBytesLeft > 0) )
737  {
738  sal_uInt16 nReadSize = GetMaxRawReadSize( nBytesLeft );
739  sal_uInt16 nReadRet = ReadRawData( pnBuffer, nReadSize );
740  nRet += nReadRet;
741  mbValid = (nReadSize == nReadRet);
742  OSL_ENSURE( mbValid, "XclImpStream::Read - stream read error" );
743  pnBuffer += nReadRet;
744  nBytesLeft -= nReadRet;
745  if( mbValid && (nBytesLeft > 0) )
747  OSL_ENSURE( mbValid, "XclImpStream::Read - record overread" );
748  }
749  }
750  return nRet;
751 }
752 
753 std::size_t XclImpStream::CopyToStream( SvStream& rOutStrm, std::size_t nBytes )
754 {
755  std::size_t nRet = 0;
756  if( mbValid && (nBytes > 0) )
757  {
758  const std::size_t nMaxBuffer = 4096;
759  std::unique_ptr<sal_uInt8[]> pnBuffer(new sal_uInt8[ ::std::min( nBytes, nMaxBuffer ) ]);
760  std::size_t nBytesLeft = nBytes;
761 
762  while( mbValid && (nBytesLeft > 0) )
763  {
764  std::size_t nReadSize = ::std::min( nBytesLeft, nMaxBuffer );
765  nRet += Read( pnBuffer.get(), nReadSize );
766  // writing more bytes than read results in invalid memory access
767  SAL_WARN_IF(nRet != nReadSize, "sc", "read less bytes than requested");
768  rOutStrm.WriteBytes(pnBuffer.get(), nReadSize);
769  nBytesLeft -= nReadSize;
770  }
771  }
772  return nRet;
773 }
774 
776 {
777  if( mbValidRec )
778  {
779  PushPosition();
781  CopyToStream( rOutStrm, GetRecSize() );
782  PopPosition();
783  }
784 }
785 
786 void XclImpStream::Seek( std::size_t nPos )
787 {
788  if( !mbValidRec )
789  return;
790 
791  std::size_t nCurrPos = GetRecPos();
792  if( !mbValid || (nPos < nCurrPos) ) // from invalid state or backward
793  {
795  Ignore( nPos );
796  }
797  else if( nPos > nCurrPos ) // forward
798  {
799  Ignore( nPos - nCurrPos );
800  }
801 }
802 
803 void XclImpStream::Ignore( std::size_t nBytes )
804 {
805  // implementation similar to Read(), but without really reading anything
806  std::size_t nBytesLeft = nBytes;
807  while( mbValid && (nBytesLeft > 0) )
808  {
809  sal_uInt16 nReadSize = GetMaxRawReadSize( nBytesLeft );
810  mbValid = checkSeek(mrStrm, mrStrm.Tell() + nReadSize);
811  mnRawRecLeft = mnRawRecLeft - nReadSize;
812  nBytesLeft -= nReadSize;
813  if (mbValid && nBytesLeft > 0)
815  OSL_ENSURE( mbValid, "XclImpStream::Ignore - record overread" );
816  }
817 }
818 
820  bool& rb16Bit, bool& rbRich, bool& rbFareast,
821  sal_uInt16& rnFormatRuns, sal_uInt32& rnExtInf, sal_uInt8 nFlags )
822 {
823  OSL_ENSURE( !::get_flag( nFlags, EXC_STRF_UNKNOWN ), "XclImpStream::ReadUniStringExt - unknown flags" );
824  rb16Bit = ::get_flag( nFlags, EXC_STRF_16BIT );
825  rbRich = ::get_flag( nFlags, EXC_STRF_RICH );
826  rbFareast = ::get_flag( nFlags, EXC_STRF_FAREAST );
827  rnFormatRuns = rbRich ? ReaduInt16() : 0;
828  rnExtInf = rbFareast ? ReaduInt32() : 0;
829  return rnExtInf + 4 * rnFormatRuns;
830 }
831 
832 std::size_t XclImpStream::ReadUniStringExtHeader( bool& rb16Bit, sal_uInt8 nFlags )
833 {
834  bool bRich, bFareast;
835  sal_uInt16 nCrun;
836  sal_uInt32 nExtInf;
837  return ReadUniStringExtHeader( rb16Bit, bRich, bFareast, nCrun, nExtInf, nFlags );
838 }
839 
840 OUString XclImpStream::ReadRawUniString( sal_uInt16 nChars, bool b16Bit )
841 {
842  OUStringBuffer aRet(std::min<sal_uInt16>(nChars, mnRawRecLeft / (b16Bit ? 2 : 1)));
843  sal_uInt16 nCharsLeft = nChars;
844  sal_uInt16 nReadSize;
845 
846  while( IsValid() && (nCharsLeft > 0) )
847  {
848  if( b16Bit )
849  {
850  nReadSize = std::min<sal_uInt16>(nCharsLeft, mnRawRecLeft / 2);
851  OSL_ENSURE( (nReadSize <= nCharsLeft) || !(mnRawRecLeft & 0x1),
852  "XclImpStream::ReadRawUniString - missing a byte" );
853  }
854  else
855  nReadSize = GetMaxRawReadSize( nCharsLeft );
856 
857  std::unique_ptr<sal_Unicode[]> pcBuffer(new sal_Unicode[nReadSize + 1]);
858 
859  sal_Unicode* pcUniChar = pcBuffer.get();
860  sal_Unicode* pcEndChar = pcBuffer.get() + nReadSize;
861 
862  if( b16Bit )
863  {
864  sal_uInt16 nReadChar;
865  for( ; IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
866  {
867  nReadChar = ReaduInt16();
868  (*pcUniChar) = (nReadChar == EXC_NUL) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
869  }
870  }
871  else
872  {
873  sal_uInt8 nReadChar;
874  for( ; IsValid() && (pcUniChar < pcEndChar); ++pcUniChar )
875  {
876  nReadChar = ReaduInt8();
877  (*pcUniChar) = (nReadChar == EXC_NUL_C) ? mcNulSubst : static_cast< sal_Unicode >( nReadChar );
878  }
879  }
880 
881  *pcEndChar = '\0';
882  // this has the side-effect of only copying as far as the first null, which appears to be intentional. e.g.
883  // see tdf#124318
884  aRet.append( pcBuffer.get() );
885 
886  nCharsLeft = nCharsLeft - nReadSize;
887  if( nCharsLeft > 0 )
888  JumpToNextStringContinue( b16Bit );
889  }
890 
891  return aRet.makeStringAndClear();
892 }
893 
894 OUString XclImpStream::ReadUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
895 {
896  bool b16Bit;
897  std::size_t nExtSize = ReadUniStringExtHeader( b16Bit, nFlags );
898  OUString aRet( ReadRawUniString( nChars, b16Bit ) );
899  Ignore( nExtSize );
900  return aRet;
901 }
902 
903 OUString XclImpStream::ReadUniString( sal_uInt16 nChars )
904 {
905  return ReadUniString( nChars, ReaduInt8() );
906 }
907 
909 {
910  return ReadUniString( ReaduInt16() );
911 }
912 
913 void XclImpStream::IgnoreRawUniString( sal_uInt16 nChars, bool b16Bit )
914 {
915  sal_uInt16 nCharsLeft = nChars;
916  sal_uInt16 nReadSize;
917 
918  while( IsValid() && (nCharsLeft > 0) )
919  {
920  if( b16Bit )
921  {
922  nReadSize = ::std::min< sal_uInt16 >( nCharsLeft, mnRawRecLeft / 2 );
923  OSL_ENSURE( (nReadSize <= nCharsLeft) || !(mnRawRecLeft & 0x1),
924  "XclImpStream::IgnoreRawUniString - missing a byte" );
925  Ignore( nReadSize * 2 );
926  }
927  else
928  {
929  nReadSize = GetMaxRawReadSize( nCharsLeft );
930  Ignore( nReadSize );
931  }
932 
933  nCharsLeft = nCharsLeft - nReadSize;
934  if( nCharsLeft > 0 )
935  JumpToNextStringContinue( b16Bit );
936  }
937 }
938 
939 void XclImpStream::IgnoreUniString( sal_uInt16 nChars, sal_uInt8 nFlags )
940 {
941  bool b16Bit;
942  std::size_t nExtSize = ReadUniStringExtHeader( b16Bit, nFlags );
943  IgnoreRawUniString( nChars, b16Bit );
944  Ignore( nExtSize );
945 }
946 
947 void XclImpStream::IgnoreUniString( sal_uInt16 nChars )
948 {
949  IgnoreUniString( nChars, ReaduInt8() );
950 }
951 
952 OUString XclImpStream::ReadRawByteString( sal_uInt16 nChars )
953 {
954  nChars = GetMaxRawReadSize(nChars);
955  std::unique_ptr<char[]> pcBuffer(new char[ nChars + 1 ]);
956  sal_uInt16 nCharsRead = ReadRawData( pcBuffer.get(), nChars );
957  pcBuffer[ nCharsRead ] = '\0';
958  OUString aRet( pcBuffer.get(), strlen(pcBuffer.get()), mrRoot.GetTextEncoding() );
959  return aRet;
960 }
961 
962 OUString XclImpStream::ReadByteString( bool b16BitLen )
963 {
964  return ReadRawByteString( b16BitLen ? ReaduInt16() : ReaduInt8() );
965 }
966 
967 // private --------------------------------------------------------------------
968 
970 {
972 }
973 
975 {
977  SetupDecrypter();
978 }
979 
981 {
982  bool bRet = checkSeek(mrStrm, mnNextRecPos) && (mnNextRecPos + 4 <= mnStreamSize);
983  if (bRet)
984  {
986  bRet = mrStrm.good();
987  }
988  return bRet;
989 }
990 
992 {
993  if( mxDecrypter )
994  mxDecrypter->Update( mrStrm, mnRawRecSize );
995 }
996 
998 {
999  // pre: mnRawRecSize contains current raw record size
1000  // pre: mrStrm points to start of raw record data
1004  SetupDecrypter(); // decrypter works on raw record level
1005 }
1006 
1008 {
1009  mnRecId = mnRawRecId;
1011  mnCurrRecSize = 0;
1013  mbHasComplRec = !mbCont;
1014  SetupRawRecord();
1015  SetNulSubstChar();
1016  EnableDecryption();
1018 }
1019 
1020 bool XclImpStream::IsContinueId( sal_uInt16 nRecId ) const
1021 {
1022  return (nRecId == EXC_ID_CONT) || (nRecId == mnAltContId);
1023 }
1024 
1026 {
1028  if( mbValid ) // do not setup a following non-CONTINUE record
1029  SetupRawRecord();
1030  return mbValid;
1031 }
1032 
1034 {
1035  OSL_ENSURE( mnRawRecLeft == 0, "XclImpStream::JumpToNextStringContinue - unexpected garbage" );
1036 
1037  if( mbCont && (GetRecLeft() > 0) )
1038  {
1040  }
1041  else if( mnRecId == EXC_ID_CONT )
1042  {
1043  // CONTINUE handling is off, but we have started reading in a CONTINUE record
1044  // -> start next CONTINUE for TXO import
1045  mbValidRec = ReadNextRawRecHeader() && ((mnRawRecId != 0) || (mnRawRecSize > 0));
1047  // we really start a new record here - no chance to return to string origin
1048  if( mbValid )
1049  SetupRecord();
1050  }
1051  else
1052  mbValid = false;
1053 
1054  if( mbValid )
1055  rb16Bit = ::get_flag( ReaduInt8(), EXC_STRF_16BIT );
1056  return mbValid;
1057 }
1058 
1059 bool XclImpStream::EnsureRawReadSize( sal_uInt16 nBytes )
1060 {
1061  if( mbValid && nBytes )
1062  {
1063  while( mbValid && !mnRawRecLeft ) JumpToNextContinue();
1064  mbValid = mbValid && (nBytes <= mnRawRecLeft);
1065  OSL_ENSURE( mbValid, "XclImpStream::EnsureRawReadSize - record overread" );
1066  }
1067  return mbValid;
1068 }
1069 
1070 sal_uInt16 XclImpStream::GetMaxRawReadSize( std::size_t nBytes ) const
1071 {
1072  return static_cast< sal_uInt16 >( ::std::min< std::size_t >( nBytes, mnRawRecLeft ) );
1073 }
1074 
1075 sal_uInt16 XclImpStream::ReadRawData( void* pData, sal_uInt16 nBytes )
1076 {
1077  OSL_ENSURE( (nBytes <= mnRawRecLeft), "XclImpStream::ReadRawData - record overread" );
1078  sal_uInt16 nRet = 0;
1079  if( mbUseDecr )
1080  nRet = mxDecrypter->Read( mrStrm, pData, nBytes );
1081  else
1082  nRet = static_cast<sal_uInt16>(mrStrm.ReadBytes(pData, nBytes));
1083  mnRawRecLeft = mnRawRecLeft - nRet;
1084  return nRet;
1085 }
1086 
1087 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString ReadRawByteString(sal_uInt16 nChars)
Reads nChar byte characters and returns the string.
Definition: xistream.cxx:952
SvStream & ReadInt16(sal_Int16 &rInt16)
bool IsValid() const
Returns true, if the decoder has been initialized correctly.
Definition: xistream.hxx:54
void SetNulSubstChar(sal_Unicode cNulSubst= '?')
Sets a replacement character for NUL characters.
Definition: xistream.hxx:431
bool InitCodec(const css::uno::Sequence< css::beans::NamedValue > &aData)
sal_uInt16 GetMaxRawReadSize(std::size_t nBytes) const
Returns the maximum size of raw data possible to read in one block.
Definition: xistream.cxx:1070
virtual XclImpBiff8CryptoAPIDecrypter * OnClone() const override
Implementation of cloning this object.
Definition: xistream.cxx:242
XclImpBiff8CryptoAPIDecrypter(const std::vector< sal_uInt8 > &rSalt, const std::vector< sal_uInt8 > &rVerifier, const std::vector< sal_uInt8 > &rVerifierHash)
Definition: xistream.hxx:178
sal_Unicode mcNulSubst
Bytes left in current raw record (without following CONTINUEs).
Definition: xistream.hxx:545
sal_uInt16 GetNextRecId()
Returns the record ID of the following record.
Definition: xistream.cxx:594
void Seek(std::size_t nPos)
Seeks absolute in record content to the specified position.
Definition: xistream.cxx:786
rtl_TextEncoding GetTextEncoding() const
Returns the text encoding to import/export byte strings.
Definition: xlroot.hxx:147
XclBiff
An enumeration for all Excel file format types (BIFF types).
Definition: xlconst.hxx:30
void Skip(std::size_t nBytes)
sal_Int32 ReadInt32()
Definition: xistream.cxx:674
std::size_t GetRecPos() const
Returns the position inside of the whole record content.
Definition: xistream.cxx:571
virtual css::uno::Sequence< css::beans::NamedValue > OnVerifyPassword(const OUString &rPassword)=0
Derived classes implement password verification and initialization of the decoder.
sal_uInt16 ReadRawData(void *pData, sal_uInt16 nBytes)
Reads and decrypts nBytes bytes to the existing(!) buffer pData.
Definition: xistream.cxx:1075
sal_uInt8 SVBT16[2]
bool EnsureRawReadSize(sal_uInt16 nBytes)
Ensures that reading nBytes bytes is possible with next stream access.
Definition: xistream.cxx:1059
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
virtual void InitKey(const sal_uInt16 pPassData[16], const sal_uInt8 pDocId[16]) override
bool VerifyKey(sal_uInt16 nKey, sal_uInt16 nHash) const
sal_uInt16 Read(SvStream &rStrm, void *pData, sal_uInt16 nBytes)
Reads and decrypts nBytes bytes and stores data into the existing(!) buffer pData.
Definition: xistream.cxx:92
void SetDecrypter(XclImpDecrypterRef const &xDecrypter)
Enables decryption of record contents for the rest of the stream.
Definition: xistream.cxx:514
virtual css::uno::Sequence< css::beans::NamedValue > OnVerifyPassword(const OUString &rPassword) override
Implements password verification and initialization of the decoder.
Definition: xistream.cxx:247
virtual sal_uInt64 TellEnd()
void RewindRecord()
Sets stream pointer before current record and invalidates stream.
Definition: xistream.cxx:508
sal_uInt16 mnAltContId
Current record ID (not the CONTINUE ID).
Definition: xistream.hxx:539
std::vector< sal_uInt8 > maVerifierHash
Definition: xistream.hxx:149
bool IsValid() const
Returns record reading state: false = record overread.
Definition: xistream.hxx:352
XclImpStream(SvStream &rInStrm, const XclImpRoot &rRoot)
Constructs the Excel record import stream using a TOOLS stream object.
Definition: xistream.cxx:434
std::size_t Read(void *pData, std::size_t nBytes)
Reads nBytes bytes to the existing(!) buffer pData.
Definition: xistream.cxx:728
virtual bool OnVerifyEncryptionData(const css::uno::Sequence< css::beans::NamedValue > &rEncryptionData) override
Definition: xistream.cxx:272
css::uno::Sequence< css::beans::NamedValue > GetEncryptionData()
#define STREAM_SEEK_TO_END
virtual ::comphelper::DocPasswordVerifierResult verifyPassword(const OUString &rPassword, css::uno::Sequence< css::beans::NamedValue > &o_rEncryptionData) override
Implementation of the comphelper::IDocPasswordVerifier interface.
Definition: xistream.cxx:64
bool IsContinueId(sal_uInt16 nRecId) const
Returns true, if the passed ID is real or alternative continuation record ID.
Definition: xistream.cxx:1020
sal_uInt64 Seek(sal_uInt64 nPos)
const sal_uInt16 EXC_ENCR_BLOCKSIZE
Definition: xlstream.hxx:34
bool InitCodec(const css::uno::Sequence< css::beans::NamedValue > &aData)
sal_uInt16 mnRawRecLeft
Current raw record size (without following CONTINUEs).
Definition: xistream.hxx:543
virtual sal_uInt16 OnRead(SvStream &rStrm, sal_uInt8 *pnData, sal_uInt16 nBytes) override
Implementation of the decryption.
Definition: xistream.cxx:194
const sal_uInt16 EXC_ID5_BOF
Definition: xlconst.hxx:156
const sal_uInt16 EXC_BOF_BIFF5
Definition: xlconst.hxx:161
bool mbValidRec
Usage of decryption.
Definition: xistream.hxx:549
virtual void OnUpdate(std::size_t nOldStrmPos, std::size_t nNewStrmPos, sal_uInt16 nRecSize)=0
Implementation of updating the decrypter.
bool JumpToNextContinue()
Goes to start of the next CONTINUE record.
Definition: xistream.cxx:1025
XclImpStreamPos maFirstRec
Provides methods to decrypt data.
Definition: xistream.hxx:523
sal_uInt8 SVBT32[4]
XclImpBiff8Decrypter(const std::vector< sal_uInt8 > &rSalt, const std::vector< sal_uInt8 > &rVerifier, const std::vector< sal_uInt8 > &rVerifierHash)
Definition: xistream.cxx:201
std::size_t mnComplRecSize
Helper for record position.
Definition: xistream.hxx:535
static sal_uInt32 GetBlock(std::size_t nStrmPos)
Returns the block number corresponding to the passed stream position.
Definition: xistream.cxx:336
sal_uInt16 sal_Unicode
void SeekGlobalPosition()
Seeks to the stored global user position.
Definition: xistream.cxx:558
XclImpBiff8StdDecrypter(const std::vector< sal_uInt8 > &rSalt, const std::vector< sal_uInt8 > &rVerifier, const std::vector< sal_uInt8 > &rVerifierHash)
Definition: xistream.hxx:156
bool mbValid
Bytes left in current raw record (without following CONTINUEs).
Definition: xistream.hxx:228
virtual void OnUpdate(std::size_t nOldStrmPos, std::size_t nNewStrmPos, sal_uInt16 nRecSize) override
Implementation of updating the decrypter.
Definition: xistream.cxx:188
MS Excel 4.0.
Definition: xlconst.hxx:35
MS Excel 8.0 (97), 9.0 (2000), 10.0 (XP), 11.0 (2003)
Definition: xlconst.hxx:37
SvStream & mrStrm
Definition: xistream.hxx:518
virtual XclImpBiff8StdDecrypter * OnClone() const override
Implementation of cloning this object.
Definition: xistream.cxx:229
const sal_uInt16 EXC_BOF_BIFF4
Definition: xlconst.hxx:160
const sal_uInt16 EXC_ID_CONT
Definition: xlstream.hxx:37
XclImpDecrypterRef mxDecrypter
Filter root data.
Definition: xistream.hxx:521
sal_uInt16 mnGlobRecId
User defined position elsewhere in stream.
Definition: xistream.hxx:528
void StorePosition(XclImpStreamPos &rPos)
Stores current stream position into rPos.
Definition: xistream.cxx:969
void SetupRecord()
Initializes all members after base stream has been sought to new record.
Definition: xistream.cxx:1007
const std::size_t EXC_REC_SEEK_TO_END
Definition: xlstream.hxx:28
XclImpStreamPos maGlobPos
Stack for record positions.
Definition: xistream.hxx:527
sal_uInt16 mnRecId
true = mnComplRecSize is valid.
Definition: xistream.hxx:538
bool mbGlobValidRec
Record ID for user defined position.
Definition: xistream.hxx:529
bool StartNextRecord()
Sets stream pointer to the start of the next record content.
Definition: xistream.cxx:463
sal_uInt16 mnRecSize
Last known stream position.
Definition: xistream.hxx:90
void PopPosition()
Seeks to last position from user position stack.
Definition: xistream.cxx:540
::msfilter::MSCodec_CryptoAPI maCodec
Definition: xistream.hxx:194
std::size_t GetPos() const
Returns the stored stream position.
Definition: xistream.hxx:219
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
virtual css::uno::Sequence< css::beans::NamedValue > GetEncryptionData()
virtual sal_uInt16 OnRead(SvStream &rStrm, sal_uInt8 *pnData, sal_uInt16 nBytes)=0
Implementation of the decryption.
bool JumpToNextStringContinue(bool &rb16Bit)
Goes to start of the next CONTINUE record while reading strings.
Definition: xistream.cxx:1033
std::vector< XclImpStreamPos > maPosStack
Start position of current record.
Definition: xistream.hxx:525
void update(const SequenceAsHashMap &rSource)
sal_Int16 ReadInt16()
Definition: xistream.cxx:638
std::size_t GetRecSize()
Returns the data size of the whole record without record headers.
Definition: xistream.cxx:576
virtual bool OnVerifyEncryptionData(const css::uno::Sequence< css::beans::NamedValue > &rEncryptionData)=0
bool mbHasComplRec
Size of complete record data (with CONTINUEs).
Definition: xistream.hxx:536
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
MS Excel 5.0, MS Excel 7.0 (95)
Definition: xlconst.hxx:36
bool checkSeek(SvStream &rSt, sal_uInt64 nOffset)
virtual ::comphelper::DocPasswordVerifierResult verifyEncryptionData(const css::uno::Sequence< css::beans::NamedValue > &rEncryptionData) override
Definition: xistream.cxx:71
sal_uInt16 mnRawRecLeft
Current raw record size (without following CONTINUEs).
Definition: xistream.hxx:227
OUString ReadRawUniString(sal_uInt16 nChars, bool b16Bit)
Reads nChars characters and returns the string.
Definition: xistream.cxx:840
DocPasswordVerifierResult
sal_uInt16 mnRawRecId
Current calculated size of the record.
Definition: xistream.hxx:225
const sal_uInt16 EXC_ID4_BOF
Definition: xlconst.hxx:155
virtual void Decode(sal_uInt8 *pnData, std::size_t nBytes) override
std::vector< sal_uInt8 > maSalt
Definition: xistream.hxx:147
std::shared_ptr< XclImpDecrypter > XclImpDecrypterRef
Definition: xistream.hxx:41
#define STREAM_SEEK_TO_BEGIN
Decrypts BIFF5 stream contents.
Definition: xistream.hxx:94
void SetupRawRecord()
Initializes all members after base stream has been sought to new raw record.
Definition: xistream.cxx:997
void SetupDecrypter()
Initializes the decrypter to read a new record.
Definition: xistream.cxx:991
void IgnoreUniString(sal_uInt16 nChars, sal_uInt8 nFlags)
Ignores ext.
Definition: xistream.cxx:939
Base class for BIFF stream decryption.
Definition: xistream.hxx:45
double ReadDouble()
Definition: xistream.cxx:710
const sal_uInt16 EXC_ID_UNKNOWN
Definition: xlstream.hxx:36
virtual css::uno::Sequence< css::beans::NamedValue > OnVerifyPassword(const OUString &rPassword) override
Implements password verification and initialization of the decoder.
Definition: xistream.cxx:130
std::size_t WriteBytes(const void *pData, std::size_t nSize)
const sal_uInt16 EXC_BOF_BIFF3
Definition: xlconst.hxx:159
void Get(SvStream &rStrm, std::size_t &rnNextPos, std::size_t &rnCurrSize, sal_uInt16 &rnRawRecId, sal_uInt16 &rnRawRecSize, sal_uInt16 &rnRawRecLeft, bool &rbValid) const
Writes the contained stream position data to the given variables.
Definition: xistream.cxx:372
bool get_flag(Type nBitField, Type nMask)
Returns true, if at least one of the bits set in nMask is set in nBitField.
Definition: ftools.hxx:76
virtual void OnUpdate(std::size_t nOldStrmPos, std::size_t nNewStrmPos, sal_uInt16 nRecSize) override
Implementation of updating the decrypter.
Definition: xistream.cxx:288
std::size_t mnPos
Definition: xistream.hxx:222
MS Excel 3.0.
Definition: xlconst.hxx:34
std::size_t mnNextPos
Absolute position of the stream.
Definition: xistream.hxx:223
OUString ReadUniString()
Reads 16 bit character count, 8 bit flags, ext.
Definition: xistream.cxx:908
std::size_t mnNextRecPos
Size of system stream.
Definition: xistream.hxx:533
const sal_uInt16 EXC_NUL
NUL character.
Definition: xlstring.hxx:54
SvStream & ReadUChar(unsigned char &rChar)
bool mbValid
false = No more records to read.
Definition: xistream.hxx:550
sal_uInt8 SVBT64[8]
const sal_uInt8 EXC_STRF_16BIT
Definition: xlstring.hxx:45
sal_Int16 nVersion
bool mbCont
Replacement for NUL characters.
Definition: xistream.hxx:547
XclImpDecrypterRef Clone() const
Creates a (ref-counted) copy of this decrypter object.
Definition: xistream.cxx:56
SvStream & ReadDouble(double &rDouble)
sal_uInt16 ReaduInt16()
Definition: xistream.cxx:656
sal_uInt64 mnOldPos
Decrypter error code.
Definition: xistream.hxx:89
Decrypts BIFF8 stream contents using the given document identifier.
Definition: xistream.hxx:122
void EnableDecryption(bool bEnable=true)
Switches usage of current decryption algorithm on/off.
Definition: xistream.cxx:529
XclImpStreamPos()
Constructs an invalid stream position data object.
Definition: xistream.cxx:347
void IgnoreRawUniString(sal_uInt16 nChars, bool b16Bit)
Ignores nChars characters.
Definition: xistream.cxx:913
void CopyDecrypterFrom(const XclImpStream &rStrm)
Sets decrypter from another stream.
Definition: xistream.cxx:521
SvStream & ReadInt32(sal_Int32 &rInt32)
std::size_t ReadBytes(void *pData, std::size_t nSize)
const sal_uInt8 EXC_STRF_RICH
Definition: xlstring.hxx:47
static css::uno::Sequence< sal_Int8 > GenerateRandomByteSequence(sal_Int32 nLength)
msfilter::MSCodec97 * mpCodec
Definition: xistream.hxx:150
std::size_t GetRecLeft()
Returns remaining data size of the whole record without record headers.
Definition: xistream.cxx:589
virtual bool OnVerifyEncryptionData(const css::uno::Sequence< css::beans::NamedValue > &rEncryptionData) override
Definition: xistream.cxx:172
XclImpBiff5Decrypter(sal_uInt16 nKey, sal_uInt16 nHash)
Definition: xistream.cxx:109
OUString ReadByteString(bool b16BitLen)
Reads 8/16 bit string length, character array and returns the string.
Definition: xistream.cxx:962
const sal_uInt8 EXC_STRF_FAREAST
Definition: xlstring.hxx:46
std::size_t ReadUniStringExtHeader(bool &rb16Bit, bool &rbRich, bool &rbFareast, sal_uInt16 &rnFormatRuns, sal_uInt32 &rnExtInf, sal_uInt8 nFlags)
Reads ext.
Definition: xistream.cxx:819
const sal_uInt8 EXC_NUL_C
LF character (unicode).
Definition: xlstring.hxx:53
virtual XclImpDecrypter * OnClone() const =0
Implementation of cloning this object.
sal_uInt16 mnRawRecSize
Current raw record ID (including CONTINUEs).
Definition: xistream.hxx:542
void CopyRecordToStream(SvStream &rOutStrm)
Copies the entire record to rOutStrm.
Definition: xistream.cxx:775
virtual XclImpBiff5Decrypter * OnClone() const override
Implementation of cloning this object.
Definition: xistream.cxx:125
#define SAL_WARN_IF(condition, area, stream)
ErrCode mnError
Definition: xistream.hxx:88
#define ERRCODE_NONE
void Ignore(std::size_t nBytes)
Seeks forward inside the current record.
Definition: xistream.cxx:803
unsigned char sal_uInt8
bool mbUseDecr
Automatic CONTINUE lookup on/off.
Definition: xistream.hxx:548
sal_uInt8 ReaduInt8()
Definition: xistream.cxx:624
bool VerifyKey(const sal_uInt8 *pSaltData, const sal_uInt8 *pSaltDigest)
::msfilter::MSCodec_Std97 maCodec
Definition: xistream.hxx:172
css::uno::Sequence< css::beans::NamedValue > maEncryptionData
Definition: xistream.hxx:146
const sal_uInt16 EXC_BOF_BIFF2
Definition: xlconst.hxx:158
void Update(const SvStream &rStrm, sal_uInt16 nRecSize)
Updates the decrypter on start of a new record or after seeking stream.
Definition: xistream.cxx:78
sal_uInt16 mnRawRecSize
Current raw record ID (including CONTINUEs).
Definition: xistream.hxx:226
bool ReadNextRawRecHeader()
Seeks to next raw record header and reads record ID and size.
Definition: xistream.cxx:980
This class represents an Excel stream position.
Definition: xistream.hxx:202
void ResetRecord(bool bContLookup, sal_uInt16 nAltContId=EXC_ID_UNKNOWN)
Sets stream pointer to begin of record content.
Definition: xistream.cxx:494
std::vector< sal_uInt8 > maVerifier
Definition: xistream.hxx:148
sal_uInt16 mnRawRecId
Alternative record ID for content continuation.
Definition: xistream.hxx:541
sal_uInt64 Tell() const
void PushPosition()
Pushes current position on user position stack.
Definition: xistream.cxx:534
const sal_uInt16 EXC_BOF_BIFF8
Definition: xlconst.hxx:162
std::size_t mnCurrRecSize
Start of next record header.
Definition: xistream.hxx:534
bool good() const
void StoreGlobalPosition()
Stores current position.
Definition: xistream.cxx:550
bool Decode(const void *pData, std::size_t nDatLen, sal_uInt8 *pBuffer, std::size_t nBufLen)
#define ERRCODE_ABORT
virtual void InitKey(const sal_uInt16 pPassData[16], const sal_uInt8 pDocId[16])=0
const sal_uInt8 EXC_STRF_UNKNOWN
Definition: xlstring.hxx:48
#define SAL_WARN(area, stream)
std::size_t mnCurrSize
Absolute position of next record.
Definition: xistream.hxx:224
const sal_uInt16 EXC_ID3_BOF
Definition: xlconst.hxx:154
virtual sal_uInt16 OnRead(SvStream &rStrm, sal_uInt8 *pnData, sal_uInt16 nBytes) override
Implementation of the decryption.
Definition: xistream.cxx:311
bool Skip(std::size_t nDatLen)
virtual ~XclImpDecrypter() override
Definition: xistream.cxx:52
MS Excel 2.1.
Definition: xlconst.hxx:33
css::uno::Sequence< css::beans::NamedValue > maEncryptionData
Crypto algorithm implementation.
Definition: xistream.hxx:116
This class is used to import record oriented streams.
Definition: xistream.hxx:278
std::size_t CopyToStream(SvStream &rOutStrm, std::size_t nBytes)
Copies nBytes bytes to rOutStrm.
Definition: xistream.cxx:753
virtual bool InitCipher(sal_uInt32 nCounter)=0
bool mbHasGlobPos
Was user position a valid record?
Definition: xistream.hxx:530
const XclImpRoot & mrRoot
Reference to the system input stream.
Definition: xistream.hxx:519
void Set(const SvStream &rStrm, std::size_t nNextPos, std::size_t nCurrSize, sal_uInt16 nRawRecId, sal_uInt16 nRawRecSize, sal_uInt16 nRawRecLeft, bool bValid)
Sets the stream position data to the passed values.
Definition: xistream.cxx:358
void InitKey(const sal_uInt8 pnPassData[16])
const ErrCode EXC_ENCR_ERROR_UNSUPP_CRYPT
Definition: xlstream.hxx:33
Access to global data from other classes.
Definition: xiroot.hxx:126
sal_uInt32 ReaduInt32()
Definition: xistream.cxx:692
const sal_uInt16 EXC_ID2_BOF
Text rotation: vertically stacked.
Definition: xlconst.hxx:153
::msfilter::MSCodec_XorXLS95 maCodec
Definition: xistream.hxx:115
sal_uInt16 PeekRecId(std::size_t nPos)
Definition: xistream.cxx:611
void RestorePosition(const XclImpStreamPos &rPos)
Restores stream position contained in rPos.
Definition: xistream.cxx:974
bool mbValid
std::size_t mnStreamSize
Is user position defined?
Definition: xistream.hxx:532
static sal_uInt16 GetOffset(std::size_t nStrmPos)
Returns the block offset corresponding to the passed stream position.
Definition: xistream.cxx:341
sal_Int16 nValue
static XclBiff DetectBiffVersion(SvStream &rStrm)
Detects the BIFF version of the passed workbook stream.
Definition: xistream.cxx:386