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