xref: /core/sc/source/filter/excel/read.cxx (revision f0a8b5b8)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <document.hxx>
21 #include <docsh.hxx>
22 #include <scerrors.hxx>
23 #include <fprogressbar.hxx>
24 #include <globstr.hrc>
25 #include <xlcontent.hxx>
26 #include <xltracer.hxx>
27 #include <xltable.hxx>
28 #include <xihelper.hxx>
29 #include <xipage.hxx>
30 #include <xiview.hxx>
31 #include <xilink.hxx>
32 #include <xiname.hxx>
33 #include <xlname.hxx>
34 #include <xicontent.hxx>
35 #include <xiescher.hxx>
36 #include <xipivot.hxx>
37 #include <xistyle.hxx>
38 #include <XclImpChangeTrack.hxx>
39 #include <documentimport.hxx>
40 
41 #include <root.hxx>
42 #include <imp_op.hxx>
43 #include <excimp8.hxx>
44 
45 #include <comphelper/configuration.hxx>
46 
47 #include <memory>
48 
49 namespace
50 {
TryStartNextRecord(XclImpStream & rIn,std::size_t nProgressBasePos)51     bool TryStartNextRecord(XclImpStream& rIn, std::size_t nProgressBasePos)
52     {
53         bool bValid = true;
54         // i#115255 fdo#40304 BOUNDSHEET doesn't point to a valid
55         // BOF record position.  Scan the records manually (from
56         // the BOUNDSHEET position) until we find a BOF.  Some 3rd
57         // party Russian programs generate invalid xls docs with
58         // this kind of silliness.
59         if (rIn.PeekRecId(nProgressBasePos) == EXC_ID5_BOF)
60             // BOUNDSHEET points to a valid BOF record.  Good.
61             rIn.StartNextRecord(nProgressBasePos);
62         else
63         {
64             while (bValid && rIn.GetRecId() != EXC_ID5_BOF)
65                 bValid = rIn.StartNextRecord();
66         }
67         return bValid;
68     }
69 }
70 
Read()71 ErrCode ImportExcel::Read()
72 {
73     XclImpPageSettings&     rPageSett       = GetPageSettings();
74     XclImpTabViewSettings&  rTabViewSett    = GetTabViewSettings();
75     XclImpPalette&          rPal            = GetPalette();
76     XclImpFontBuffer&       rFontBfr        = GetFontBuffer();
77     XclImpNumFmtBuffer&     rNumFmtBfr      = GetNumFmtBuffer();
78     XclImpXFBuffer&         rXFBfr          = GetXFBuffer();
79     XclImpNameManager&      rNameMgr        = GetNameManager();
80     // call to GetCurrSheetDrawing() cannot be cached (changes in new sheets)
81 
82     enum STATE {
83         Z_BiffNull, // not a valid Biff-Format
84         Z_Biff2,    // Biff2: only one table
85 
86         Z_Biff3,    // Biff3: only one table
87 
88         Z_Biff4,    // Biff4: only one table
89         Z_Biff4W,   // Biff4 Workbook: Globals
90         Z_Biff4T,   // Biff4 Workbook: a table itself
91         Z_Biff4E,   // Biff4 Workbook: between tables
92 
93         Z_Biff5WPre,// Biff5: Prefetch Workbook
94         Z_Biff5W,   // Biff5: Globals
95         Z_Biff5TPre,// Biff5: Prefetch for Shrfmla/Array Formula
96         Z_Biff5T,   // Biff5: a table itself
97         Z_Biff5E,   // Biff5: between tables
98         Z_Biffn0,   // all Biffs: skip table till next EOF
99         Z_End };
100 
101     STATE           eCurrent = Z_BiffNull, ePrev = Z_BiffNull;
102 
103     ErrCode         eLastErr = ERRCODE_NONE;
104     sal_uInt16      nOpcode;
105     sal_uInt16      nBofLevel = 0;
106 
107     std::unique_ptr< ScfSimpleProgressBar > pProgress( new ScfSimpleProgressBar(
108         aIn.GetSvStreamSize(), GetDocShell(), STR_LOAD_DOC ) );
109 
110     /*  #i104057# Need to track a base position for progress bar calculation,
111         because sheet substreams may not be in order of sheets. */
112     std::size_t nProgressBasePos = 0;
113     std::size_t nProgressBaseSize = 0;
114 
115     for (; eCurrent != Z_End; mnLastRecId = nOpcode)
116     {
117         if( eCurrent == Z_Biff5E )
118         {
119             sal_uInt16 nScTab = GetCurrScTab();
120             if( nScTab < maSheetOffsets.size()  )
121             {
122                 nProgressBaseSize += (aIn.GetSvStreamPos() - nProgressBasePos);
123                 nProgressBasePos = maSheetOffsets[ nScTab ];
124 
125                 bool bValid = TryStartNextRecord(aIn, nProgressBasePos);
126                 if (!bValid)
127                 {
128                     // Safeguard ourselves from potential infinite loop.
129                     eCurrent = Z_End;
130                 }
131             }
132             else
133                 eCurrent = Z_End;
134         }
135         else
136             aIn.StartNextRecord();
137 
138         nOpcode = aIn.GetRecId();
139 
140         if( !aIn.IsValid() )
141         {
142             // finalize table if EOF is missing
143             switch( eCurrent )
144             {
145                 case Z_Biff2:
146                 case Z_Biff3:
147                 case Z_Biff4:
148                 case Z_Biff4T:
149                 case Z_Biff5TPre:
150                 case Z_Biff5T:
151                     rNumFmtBfr.CreateScFormats();
152                     Eof();
153                 break;
154                 default:;
155             }
156             break;
157         }
158 
159         if( eCurrent == Z_End )
160             break;
161 
162         if( eCurrent != Z_Biff5TPre && eCurrent != Z_Biff5WPre )
163             pProgress->ProgressAbs( nProgressBaseSize + aIn.GetSvStreamPos() - nProgressBasePos );
164 
165         switch( eCurrent )
166         {
167 
168             case Z_BiffNull:    // ------------------------------- Z_BiffNull -
169             {
170                 switch( nOpcode )
171                 {
172                     case EXC_ID2_BOF:
173                     case EXC_ID3_BOF:
174                     case EXC_ID4_BOF:
175                     case EXC_ID5_BOF:
176                     {
177                         // #i23425# don't rely on the record ID, but on the detected BIFF version
178                         switch( GetBiff() )
179                         {
180                             case EXC_BIFF2:
181                                 Bof2();
182                                 if( pExcRoot->eDateiTyp == Biff2 )
183                                 {
184                                     eCurrent = Z_Biff2;
185                                     NewTable();
186                                 }
187                             break;
188                             case EXC_BIFF3:
189                                 Bof3();
190                                 if( pExcRoot->eDateiTyp == Biff3 )
191                                 {
192                                     eCurrent = Z_Biff3;
193                                     NewTable();
194                                 }
195                             break;
196                             case EXC_BIFF4:
197                                 Bof4();
198                                 if( pExcRoot->eDateiTyp == Biff4 )
199                                 {
200                                     eCurrent = Z_Biff4;
201                                     NewTable();
202                                 }
203                                 else if( pExcRoot->eDateiTyp == Biff4W )
204                                     eCurrent = Z_Biff4W;
205                             break;
206                             case EXC_BIFF5:
207                                 Bof5();
208                                 if( pExcRoot->eDateiTyp == Biff5W )
209                                 {
210                                     eCurrent = Z_Biff5WPre;
211 
212                                     nBdshtTab = 0;
213 
214                                     aIn.StoreGlobalPosition(); // store position
215                                 }
216                                 else if( pExcRoot->eDateiTyp == Biff5 )
217                                 {
218                                     // #i62752# possible to have BIFF5 sheet without globals
219                                     NewTable();
220                                     eCurrent = Z_Biff5TPre;  // Shrfmla Prefetch, Row-Prefetch
221                                     nBofLevel = 0;
222                                     aIn.StoreGlobalPosition(); // store position
223                                 }
224                             break;
225                             default:
226                                 DBG_ERROR_BIFF();
227                         }
228                     }
229                     break;
230                 }
231             }
232                 break;
233 
234             case Z_Biff2:       // ---------------------------------- Z_Biff2 -
235             {
236                 switch( nOpcode )
237                 {
238                     case EXC_ID2_DIMENSIONS:
239                     case EXC_ID3_DIMENSIONS:    ReadDimensions();       break;
240                     case EXC_ID2_BLANK:
241                     case EXC_ID3_BLANK:         ReadBlank();            break;
242                     case EXC_ID2_INTEGER:       ReadInteger();          break;
243                     case EXC_ID2_NUMBER:
244                     case EXC_ID3_NUMBER:        ReadNumber();           break;
245                     case EXC_ID2_LABEL:
246                     case EXC_ID3_LABEL:         ReadLabel();            break;
247                     case EXC_ID2_BOOLERR:
248                     case EXC_ID3_BOOLERR:       ReadBoolErr();          break;
249                     case EXC_ID_RK:             ReadRk();               break;
250 
251                     case 0x06:  Formula25(); break;     // FORMULA      [ 2  5]
252                     case 0x08:  Row25(); break;         // ROW          [ 2  5]
253                     case 0x0A:                          // EOF          [ 2345]
254                         rNumFmtBfr.CreateScFormats();
255                         rNameMgr.ConvertAllTokens();
256                         Eof();
257                         eCurrent = Z_End;
258                         break;
259                     case 0x14:
260                     case 0x15:  rPageSett.ReadHeaderFooter( maStrm );   break;
261                     case 0x17:  Externsheet(); break;   // EXTERNSHEET  [ 2345]
262                     case 0x18:  rNameMgr.ReadName( maStrm );            break;
263                     case 0x1C:  GetCurrSheetDrawing().ReadNote( maStrm );break;
264                     case 0x1D:  rTabViewSett.ReadSelection( maStrm );   break;
265                     case 0x1E:  rNumFmtBfr.ReadFormat( maStrm );        break;
266                     case 0x20:  Columndefault(); break; // COLUMNDEFAULT[ 2   ]
267                     case 0x21:  Array25(); break;       // ARRAY        [ 2  5]
268                     case 0x23:  Externname25(); break;  // EXTERNNAME   [ 2  5]
269                     case 0x24:  Colwidth(); break;      // COLWIDTH     [ 2   ]
270                     case 0x25:  Defrowheight2(); break; // DEFAULTROWHEI[ 2   ]
271                     case 0x26:
272                     case 0x27:
273                     case 0x28:
274                     case 0x29:  rPageSett.ReadMargin( maStrm );         break;
275                     case 0x2A:  rPageSett.ReadPrintHeaders( maStrm );   break;
276                     case 0x2B:  rPageSett.ReadPrintGridLines( maStrm ); break;
277                     case 0x2F:                          // FILEPASS     [ 2345]
278                         eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
279                         if( eLastErr != ERRCODE_NONE )
280                             eCurrent = Z_End;
281                         break;
282                     case EXC_ID2_FONT:  rFontBfr.ReadFont( maStrm );    break;
283                     case EXC_ID_EFONT:  rFontBfr.ReadEfont( maStrm );   break;
284                     case 0x3E:  rTabViewSett.ReadWindow2( maStrm, false );break;
285                     case 0x41:  rTabViewSett.ReadPane( maStrm );        break;
286                     case 0x42:  Codepage(); break;      // CODEPAGE     [ 2345]
287                     case 0x43:  rXFBfr.ReadXF( maStrm );                break;
288                     case 0x44:  Ixfe(); break;          // IXFE         [ 2   ]
289                 }
290             }
291                 break;
292 
293             case Z_Biff3:       // ---------------------------------- Z_Biff3 -
294             {
295                 switch( nOpcode )
296                 {
297                     // skip chart substream
298                     case EXC_ID2_BOF:
299                     case EXC_ID3_BOF:
300                     case EXC_ID4_BOF:
301                     case EXC_ID5_BOF:           XclTools::SkipSubStream( maStrm );  break;
302 
303                     case EXC_ID2_DIMENSIONS:
304                     case EXC_ID3_DIMENSIONS:    ReadDimensions();       break;
305                     case EXC_ID2_BLANK:
306                     case EXC_ID3_BLANK:         ReadBlank();            break;
307                     case EXC_ID2_INTEGER:       ReadInteger();          break;
308                     case EXC_ID2_NUMBER:
309                     case EXC_ID3_NUMBER:        ReadNumber();           break;
310                     case EXC_ID2_LABEL:
311                     case EXC_ID3_LABEL:         ReadLabel();            break;
312                     case EXC_ID2_BOOLERR:
313                     case EXC_ID3_BOOLERR:       ReadBoolErr();          break;
314                     case EXC_ID_RK:             ReadRk();               break;
315 
316                     case 0x0A:                          // EOF          [ 2345]
317                         rNumFmtBfr.CreateScFormats();
318                         rNameMgr.ConvertAllTokens();
319                         Eof();
320                         eCurrent = Z_End;
321                         break;
322                     case 0x14:
323                     case 0x15:  rPageSett.ReadHeaderFooter( maStrm );   break;
324                     case 0x17:  Externsheet(); break;   // EXTERNSHEET  [ 2345]
325                     case 0x1A:
326                     case 0x1B:  rPageSett.ReadPageBreaks( maStrm );     break;
327                     case 0x1C:  GetCurrSheetDrawing().ReadNote( maStrm );break;
328                     case 0x1D:  rTabViewSett.ReadSelection( maStrm );   break;
329                     case 0x1E:  rNumFmtBfr.ReadFormat( maStrm );        break;
330                     case 0x22:  Rec1904(); break;       // 1904         [ 2345]
331                     case 0x26:
332                     case 0x27:
333                     case 0x28:
334                     case 0x29:  rPageSett.ReadMargin( maStrm );         break;
335                     case 0x2A:  rPageSett.ReadPrintHeaders( maStrm );   break;
336                     case 0x2B:  rPageSett.ReadPrintGridLines( maStrm ); break;
337                     case 0x2F:                          // FILEPASS     [ 2345]
338                         eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
339                         if( eLastErr != ERRCODE_NONE )
340                             eCurrent = Z_End;
341                         break;
342                     case EXC_ID_FILESHARING: ReadFileSharing();         break;
343                     case 0x41:  rTabViewSett.ReadPane( maStrm );        break;
344                     case 0x42:  Codepage(); break;      // CODEPAGE     [ 2345]
345                     case 0x56:  break;                  // BUILTINFMTCNT[  34 ]
346                     case 0x5D:  GetCurrSheetDrawing().ReadObj( maStrm );break;
347                     case 0x7D:  Colinfo(); break;       // COLINFO      [  345]
348                     case 0x8C:  Country(); break;       // COUNTRY      [  345]
349                     case 0x92:  rPal.ReadPalette( maStrm );             break;
350                     case 0x0206: Formula3(); break;     // FORMULA      [  3  ]
351                     case 0x0208: Row34(); break;        // ROW          [  34 ]
352                     case 0x0218: rNameMgr.ReadName( maStrm );           break;
353                     case 0x0221: Array34(); break;      // ARRAY        [  34 ]
354                     case 0x0223: break;                 // EXTERNNAME   [  34 ]
355                     case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[  345]
356                     case 0x0231: rFontBfr.ReadFont( maStrm );           break;
357                     case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
358                     case 0x0243: rXFBfr.ReadXF( maStrm );               break;
359                     case 0x0293: rXFBfr.ReadStyle( maStrm );            break;
360                 }
361             }
362                 break;
363 
364             case Z_Biff4:       // ---------------------------------- Z_Biff4 -
365             {
366                 switch( nOpcode )
367                 {
368                     // skip chart substream
369                     case EXC_ID2_BOF:
370                     case EXC_ID3_BOF:
371                     case EXC_ID4_BOF:
372                     case EXC_ID5_BOF:           XclTools::SkipSubStream( maStrm );  break;
373 
374                     case EXC_ID2_DIMENSIONS:
375                     case EXC_ID3_DIMENSIONS:    ReadDimensions();       break;
376                     case EXC_ID2_BLANK:
377                     case EXC_ID3_BLANK:         ReadBlank();            break;
378                     case EXC_ID2_INTEGER:       ReadInteger();          break;
379                     case EXC_ID2_NUMBER:
380                     case EXC_ID3_NUMBER:        ReadNumber();           break;
381                     case EXC_ID2_LABEL:
382                     case EXC_ID3_LABEL:         ReadLabel();            break;
383                     case EXC_ID2_BOOLERR:
384                     case EXC_ID3_BOOLERR:       ReadBoolErr();          break;
385                     case EXC_ID_RK:             ReadRk();               break;
386 
387                     case 0x0A:                          // EOF          [ 2345]
388                         rNumFmtBfr.CreateScFormats();
389                         rNameMgr.ConvertAllTokens();
390                         Eof();
391                         eCurrent = Z_End;
392                         break;
393                     case 0x12:  SheetProtect(); break;       // SHEET PROTECTION
394                     case 0x14:
395                     case 0x15:  rPageSett.ReadHeaderFooter( maStrm );   break;
396                     case 0x17:  Externsheet(); break;   // EXTERNSHEET  [ 2345]
397                     case 0x1A:
398                     case 0x1B:  rPageSett.ReadPageBreaks( maStrm );     break;
399                     case 0x1C:  GetCurrSheetDrawing().ReadNote( maStrm );break;
400                     case 0x1D:  rTabViewSett.ReadSelection( maStrm );   break;
401                     case 0x22:  Rec1904(); break;       // 1904         [ 2345]
402                     case 0x26:
403                     case 0x27:
404                     case 0x28:
405                     case 0x29:  rPageSett.ReadMargin( maStrm );         break;
406                     case 0x2A:  rPageSett.ReadPrintHeaders( maStrm );   break;
407                     case 0x2B:  rPageSett.ReadPrintGridLines( maStrm ); break;
408                     case 0x2F:                          // FILEPASS     [ 2345]
409                         eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
410                         if( eLastErr != ERRCODE_NONE )
411                             eCurrent = Z_End;
412                         break;
413                     case EXC_ID_FILESHARING: ReadFileSharing();         break;
414                     case 0x41:  rTabViewSett.ReadPane( maStrm );        break;
415                     case 0x42:  Codepage(); break;      // CODEPAGE     [ 2345]
416                     case 0x55:  DefColWidth(); break;
417                     case 0x56:  break;                  // BUILTINFMTCNT[  34 ]
418                     case 0x5D:  GetCurrSheetDrawing().ReadObj( maStrm );break;
419                     case 0x7D:  Colinfo(); break;       // COLINFO      [  345]
420                     case 0x8C:  Country(); break;       // COUNTRY      [  345]
421                     case 0x92:  rPal.ReadPalette( maStrm );             break;
422                     case 0x99:  Standardwidth(); break; // STANDARDWIDTH[   45]
423                     case 0xA1:  rPageSett.ReadSetup( maStrm );          break;
424                     case 0x0208: Row34(); break;        // ROW          [  34 ]
425                     case 0x0218: rNameMgr.ReadName( maStrm );           break;
426                     case 0x0221: Array34(); break;      // ARRAY        [  34 ]
427                     case 0x0223: break;                 // EXTERNNAME   [  34 ]
428                     case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[  345]
429                     case 0x0231: rFontBfr.ReadFont( maStrm );           break;
430                     case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
431                     case 0x0406: Formula4(); break;     // FORMULA      [   4 ]
432                     case 0x041E: rNumFmtBfr.ReadFormat( maStrm );       break;
433                     case 0x0443: rXFBfr.ReadXF( maStrm );               break;
434                     case 0x0293: rXFBfr.ReadStyle( maStrm );            break;
435                 }
436             }
437                 break;
438 
439             case Z_Biff4W:      // --------------------------------- Z_Biff4W -
440             {
441                 switch( nOpcode )
442                 {
443                     case 0x0A:                          // EOF          [ 2345]
444                         rNameMgr.ConvertAllTokens();
445                         eCurrent = Z_End;
446                         break;
447                     case 0x12:  DocProtect(); break;    // PROTECT      [    5]
448                     case 0x2F:                          // FILEPASS     [ 2345]
449                         eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
450                         if( eLastErr != ERRCODE_NONE )
451                             eCurrent = Z_End;
452                         break;
453                     case EXC_ID_FILESHARING: ReadFileSharing();         break;
454                     case 0x17:  Externsheet(); break;   // EXTERNSHEET  [ 2345]
455                     case 0x42:  Codepage(); break;      // CODEPAGE     [ 2345]
456                     case 0x55:  DefColWidth(); break;
457                     case 0x56:  break;                  // BUILTINFMTCNT[  34 ]
458                     case 0x8C:  Country(); break;       // COUNTRY      [  345]
459                     case 0x8F:  break;                  // BUNDLEHEADER [   4 ]
460                     case 0x92:  rPal.ReadPalette( maStrm );             break;
461                     case 0x99:  Standardwidth(); break; // STANDARDWIDTH[   45]
462                     case 0x0218: rNameMgr.ReadName( maStrm );           break;
463                     case 0x0223: break;                 // EXTERNNAME   [  34 ]
464                     case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[  345]
465                     case 0x0231: rFontBfr.ReadFont( maStrm );           break;
466                     case EXC_ID4_BOF:                   // BOF          [   4 ]
467                         Bof4();
468                         if( pExcRoot->eDateiTyp == Biff4 )
469                         {
470                             eCurrent = Z_Biff4T;
471                             NewTable();
472                         }
473                         else
474                             eCurrent = Z_End;
475                         break;
476                     case 0x041E: rNumFmtBfr.ReadFormat( maStrm );       break;
477                     case 0x0443: rXFBfr.ReadXF( maStrm );               break;
478                     case 0x0293: rXFBfr.ReadStyle( maStrm );            break;
479                 }
480 
481             }
482                 break;
483 
484             case Z_Biff4T:       // --------------------------------- Z_Biff4T -
485             {
486                 switch( nOpcode )
487                 {
488                     // skip chart substream
489                     case EXC_ID2_BOF:
490                     case EXC_ID3_BOF:
491                     case EXC_ID4_BOF:
492                     case EXC_ID5_BOF:           XclTools::SkipSubStream( maStrm );  break;
493 
494                     case EXC_ID2_DIMENSIONS:
495                     case EXC_ID3_DIMENSIONS:    ReadDimensions();       break;
496                     case EXC_ID2_BLANK:
497                     case EXC_ID3_BLANK:         ReadBlank();            break;
498                     case EXC_ID2_INTEGER:       ReadInteger();          break;
499                     case EXC_ID2_NUMBER:
500                     case EXC_ID3_NUMBER:        ReadNumber();           break;
501                     case EXC_ID2_LABEL:
502                     case EXC_ID3_LABEL:         ReadLabel();            break;
503                     case EXC_ID2_BOOLERR:
504                     case EXC_ID3_BOOLERR:       ReadBoolErr();          break;
505                     case EXC_ID_RK:             ReadRk();               break;
506 
507                     case 0x0A:                          // EOF          [ 2345]
508                         rNameMgr.ConvertAllTokens();
509                         Eof();
510                         eCurrent = Z_Biff4E;
511                     break;
512                     case 0x12:  SheetProtect(); break;       // SHEET PROTECTION
513                     case 0x14:
514                     case 0x15:  rPageSett.ReadHeaderFooter( maStrm );   break;
515                     case 0x1A:
516                     case 0x1B:  rPageSett.ReadPageBreaks( maStrm );     break;
517                     case 0x1C:  GetCurrSheetDrawing().ReadNote( maStrm );break;
518                     case 0x1D:  rTabViewSett.ReadSelection( maStrm );   break;
519                     case 0x2F:                          // FILEPASS     [ 2345]
520                         eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
521                         if( eLastErr != ERRCODE_NONE )
522                             eCurrent = Z_End;
523                         break;
524                     case 0x41:  rTabViewSett.ReadPane( maStrm );        break;
525                     case 0x42:  Codepage(); break;      // CODEPAGE     [ 2345]
526                     case 0x55:  DefColWidth(); break;
527                     case 0x56:  break;                  // BUILTINFMTCNT[  34 ]
528                     case 0x5D:  GetCurrSheetDrawing().ReadObj( maStrm );break;
529                     case 0x7D:  Colinfo(); break;       // COLINFO      [  345]
530                     case 0x8C:  Country(); break;       // COUNTRY      [  345]
531                     case 0x8F:  break;                  // BUNDLEHEADER [   4 ]
532                     case 0x92:  rPal.ReadPalette( maStrm );             break;
533                     case 0x99:  Standardwidth(); break; // STANDARDWIDTH[   45]
534                     case 0xA1:  rPageSett.ReadSetup( maStrm );          break;
535                     case 0x0208: Row34(); break;        // ROW          [  34 ]
536                     case 0x0218: rNameMgr.ReadName( maStrm );           break;
537                     case 0x0221: Array34(); break;
538                     case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[  345]
539                     case 0x0231: rFontBfr.ReadFont( maStrm );           break;
540                     case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
541                     case 0x0406: Formula4(); break;
542                     case 0x041E: rNumFmtBfr.ReadFormat( maStrm );       break;
543                     case 0x0443: rXFBfr.ReadXF( maStrm );               break;
544                     case 0x0293: rXFBfr.ReadStyle( maStrm );            break;
545                 }
546 
547             }
548                 break;
549 
550             case Z_Biff4E:      // --------------------------------- Z_Biff4E -
551             {
552                 switch( nOpcode )
553                 {
554                     case 0x0A:                          // EOF          [ 2345]
555                         eCurrent = Z_End;
556                         break;
557                     case 0x8F:  break;                  // BUNDLEHEADER [   4 ]
558                     case EXC_ID4_BOF:                   // BOF          [   4 ]
559                         Bof4();
560                         NewTable();
561                         if( pExcRoot->eDateiTyp == Biff4 )
562                         {
563                             eCurrent = Z_Biff4T;
564                         }
565                         else
566                         {
567                             ePrev = eCurrent;
568                             eCurrent = Z_Biffn0;
569                         }
570                         break;
571                 }
572 
573             }
574                 break;
575             case Z_Biff5WPre:   // ------------------------------ Z_Biff5WPre -
576             {
577                 switch( nOpcode )
578                 {
579                     case 0x0A:                          // EOF          [ 2345]
580                         eCurrent = Z_Biff5W;
581                         aIn.SeekGlobalPosition();  // and back to old position
582                         break;
583                     case 0x12:  DocProtect(); break;    // PROTECT      [    5]
584                     case 0x2F:                          // FILEPASS     [ 2345]
585                         eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
586                         if( eLastErr != ERRCODE_NONE )
587                             eCurrent = Z_End;
588                         break;
589                     case EXC_ID_FILESHARING: ReadFileSharing();         break;
590                     case 0x3D:  Window1(); break;
591                     case 0x42:  Codepage(); break;      // CODEPAGE     [ 2345]
592                     case 0x85:  Boundsheet(); break;    // BOUNDSHEET   [    5]
593                     case 0x8C:  Country(); break;       // COUNTRY      [  345]
594                     // PALETTE follows XFs, but already needed while reading the XFs
595                     case 0x92:  rPal.ReadPalette( maStrm );             break;
596                 }
597             }
598                 break;
599             case Z_Biff5W:      // --------------------------------- Z_Biff5W -
600             {
601                 switch( nOpcode )
602                 {
603                     case 0x0A:                          // EOF          [ 2345]
604                         rNumFmtBfr.CreateScFormats();
605                         rXFBfr.CreateUserStyles();
606                         rNameMgr.ConvertAllTokens();
607                         eCurrent = Z_Biff5E;
608                         break;
609                     case 0x18:  rNameMgr.ReadName( maStrm );            break;
610                     case 0x1E:  rNumFmtBfr.ReadFormat( maStrm );        break;
611                     case 0x22:  Rec1904(); break;       // 1904         [ 2345]
612                     case 0x31:  rFontBfr.ReadFont( maStrm );            break;
613                     case 0x56:  break;                  // BUILTINFMTCNT[  34 ]
614                     case 0x8D:  Hideobj(); break;       // HIDEOBJ      [  345]
615                     case 0xDE:  Olesize(); break;
616                     case 0xE0:  rXFBfr.ReadXF( maStrm );                break;
617                     case 0x0293: rXFBfr.ReadStyle( maStrm );            break;
618                     case 0x041E: rNumFmtBfr.ReadFormat( maStrm );       break;
619                 }
620 
621             }
622                 break;
623 
624             case Z_Biff5TPre:   // ------------------------------- Z_Biff5Pre -
625             {
626                 if (nOpcode == EXC_ID5_BOF)
627                     nBofLevel++;
628                 else if( (nOpcode == 0x000A) && nBofLevel )
629                     nBofLevel--;
630                 else if( !nBofLevel )                       // don't read chart records
631                 {
632                     switch( nOpcode )
633                     {
634                         case EXC_ID2_DIMENSIONS:
635                         case EXC_ID3_DIMENSIONS:    ReadDimensions();       break;
636                         case 0x08:  Row25(); break;         // ROW          [ 2  5]
637                         case 0x0A:                          // EOF          [ 2345]
638                             eCurrent = Z_Biff5T;
639                             aIn.SeekGlobalPosition(); // and back to old position
640                             break;
641                         case 0x12:  SheetProtect(); break;       // SHEET PROTECTION
642                         case 0x1A:
643                         case 0x1B:  rPageSett.ReadPageBreaks( maStrm );     break;
644                         case 0x1D:  rTabViewSett.ReadSelection( maStrm );   break;
645                         case 0x17:  Externsheet(); break;   // EXTERNSHEET  [ 2345]
646                         case 0x21:  Array25(); break;       // ARRAY        [ 2  5]
647                         case 0x23:  Externname25(); break;  // EXTERNNAME   [ 2  5]
648                         case 0x41:  rTabViewSett.ReadPane( maStrm );        break;
649                         case 0x42:  Codepage(); break;      // CODEPAGE     [ 2345]
650                         case 0x55:  DefColWidth(); break;
651                         case 0x7D:  Colinfo(); break;       // COLINFO      [  345]
652                         case 0x81:  Wsbool(); break;        // WSBOOL       [ 2345]
653                         case 0x8C:  Country(); break;       // COUNTRY      [  345]
654                         case 0x99:  Standardwidth(); break; // STANDARDWIDTH[   45]
655                         case 0x0208: Row34(); break;        // ROW          [  34 ]
656                         case 0x0221: Array34(); break;      // ARRAY        [  34 ]
657                         case 0x0223: break;                 // EXTERNNAME   [  34 ]
658                         case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[  345]
659                         case 0x023E: rTabViewSett.ReadWindow2( maStrm, false );break;
660                     }
661                 }
662             }
663                 break;
664 
665             case Z_Biff5T:       // --------------------------------- Z_Biff5T -
666             {
667                 switch( nOpcode )
668                 {
669                     case EXC_ID2_BLANK:
670                     case EXC_ID3_BLANK:         ReadBlank();            break;
671                     case EXC_ID2_INTEGER:       ReadInteger();          break;
672                     case EXC_ID2_NUMBER:
673                     case EXC_ID3_NUMBER:        ReadNumber();           break;
674                     case EXC_ID2_LABEL:
675                     case EXC_ID3_LABEL:         ReadLabel();            break;
676                     case EXC_ID2_BOOLERR:
677                     case EXC_ID3_BOOLERR:       ReadBoolErr();          break;
678                     case EXC_ID_RK:             ReadRk();               break;
679 
680                     case EXC_ID2_FORMULA:
681                     case EXC_ID3_FORMULA:
682                     case EXC_ID4_FORMULA:       Formula25(); break;
683                     case EXC_ID_SHRFMLA: Shrfmla(); break;
684                     case 0x0A:  Eof(); eCurrent = Z_Biff5E;                 break;
685                     case 0x14:
686                     case 0x15:  rPageSett.ReadHeaderFooter( maStrm );   break;
687                     case 0x17:  Externsheet(); break;   // EXTERNSHEET  [ 2345]
688                     case 0x1C:  GetCurrSheetDrawing().ReadNote( maStrm );break;
689                     case 0x1D:  rTabViewSett.ReadSelection( maStrm );   break;
690                     case 0x23:  Externname25(); break;  // EXTERNNAME   [ 2  5]
691                     case 0x26:
692                     case 0x27:
693                     case 0x28:
694                     case 0x29:  rPageSett.ReadMargin( maStrm );         break;
695                     case 0x2A:  rPageSett.ReadPrintHeaders( maStrm );   break;
696                     case 0x2B:  rPageSett.ReadPrintGridLines( maStrm ); break;
697                     case 0x2F:                          // FILEPASS     [ 2345]
698                         eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
699                         if( eLastErr != ERRCODE_NONE )
700                             eCurrent = Z_End;
701                         break;
702                     case 0x5D:  GetCurrSheetDrawing().ReadObj( maStrm );break;
703                     case 0x83:
704                     case 0x84:  rPageSett.ReadCenter( maStrm );         break;
705                     case 0xA0:  rTabViewSett.ReadScl( maStrm );         break;
706                     case 0xA1:  rPageSett.ReadSetup( maStrm );          break;
707                     case 0xBD:  Mulrk(); break;         // MULRK        [    5]
708                     case 0xBE:  Mulblank(); break;      // MULBLANK     [    5]
709                     case 0xD6:  Rstring(); break;       // RSTRING      [    5]
710                     case 0x00E5: Cellmerging();          break;  // #i62300#
711                     case 0x0236: TableOp(); break;      // TABLE        [    5]
712                     case EXC_ID5_BOF:                   // BOF          [    5]
713                         XclTools::SkipSubStream( maStrm );
714                         break;
715                 }
716 
717             }
718                 break;
719 
720             case Z_Biff5E:      // --------------------------------- Z_Biff5E -
721             {
722                 switch( nOpcode )
723                 {
724                     case EXC_ID5_BOF:                   // BOF          [    5]
725                         Bof5();
726                         NewTable();
727                         switch( pExcRoot->eDateiTyp )
728                         {
729                             case Biff5:
730                             case Biff5M4:
731                                 eCurrent = Z_Biff5TPre; // Shrfmla Prefetch, Row-Prefetch
732                                 nBofLevel = 0;
733                                 aIn.StoreGlobalPosition(); // store position
734                             break;
735                             case Biff5C:    // chart sheet
736                                 GetCurrSheetDrawing().ReadTabChart( maStrm );
737                                 Eof();
738                                 GetTracer().TraceChartOnlySheet();
739                             break;
740                             case Biff5V:
741                             default:
742                                 rD.SetVisible( GetCurrScTab(), false );
743                                 ePrev = eCurrent;
744                                 eCurrent = Z_Biffn0;
745                         }
746                         OSL_ENSURE( pExcRoot->eDateiTyp != Biff5W,
747                             "+ImportExcel::Read(): Doppel-Whopper-Workbook!" );
748 
749                         break;
750                 }
751 
752             }
753                 break;
754             case Z_Biffn0:      // --------------------------------- Z_Biffn0 -
755             {
756                 switch( nOpcode )
757                 {
758                     case 0x0A:                          // EOF          [ 2345]
759                         eCurrent = ePrev;
760                         IncCurrScTab();
761                         break;
762                 }
763 
764             }
765                 break;
766 
767             case Z_End:        // ----------------------------------- Z_End -
768                 OSL_FAIL( "*ImportExcel::Read(): Not possible state!" );
769                 break;
770             default: OSL_FAIL( "-ImportExcel::Read(): state forgotten!" );
771         }
772     }
773 
774     if( eLastErr == ERRCODE_NONE )
775     {
776         pProgress.reset();
777 
778         GetDocImport().finalize();
779         if (!comphelper::IsFuzzing())
780             AdjustRowHeight();
781         PostDocLoad();
782 
783         rD.CalcAfterLoad(false);
784 
785         const XclImpAddressConverter& rAddrConv = GetAddressConverter();
786         if( rAddrConv.IsTabTruncated() )
787             eLastErr = SCWARN_IMPORT_SHEET_OVERFLOW;
788         else if( bTabTruncated || rAddrConv.IsRowTruncated() )
789             eLastErr = SCWARN_IMPORT_ROW_OVERFLOW;
790         else if( rAddrConv.IsColTruncated() )
791             eLastErr = SCWARN_IMPORT_COLUMN_OVERFLOW;
792     }
793 
794     return eLastErr;
795 }
796 
Read()797 ErrCode ImportExcel8::Read()
798 {
799 #ifdef EXC_INCL_DUMPER
800     {
801         Biff8RecDumper aDumper( GetRoot(), sal_True );
802         if( aDumper.Dump( aIn ) )
803             return ERRCODE_ABORT;
804     }
805 #endif
806     // read the entire BIFF8 stream
807     // don't look too close - this stuff seriously needs to be reworked
808 
809     XclImpPageSettings&     rPageSett       = GetPageSettings();
810     XclImpTabViewSettings&  rTabViewSett    = GetTabViewSettings();
811     XclImpPalette&          rPal            = GetPalette();
812     XclImpFontBuffer&       rFontBfr        = GetFontBuffer();
813     XclImpNumFmtBuffer&     rNumFmtBfr      = GetNumFmtBuffer();
814     XclImpXFBuffer&         rXFBfr          = GetXFBuffer();
815     XclImpSst&              rSst            = GetSst();
816     XclImpTabInfo&          rTabInfo        = GetTabInfo();
817     XclImpNameManager&      rNameMgr        = GetNameManager();
818     XclImpLinkManager&      rLinkMgr        = GetLinkManager();
819     XclImpObjectManager&    rObjMgr         = GetObjectManager();
820     // call to GetCurrSheetDrawing() cannot be cached (changes in new sheets)
821     XclImpCondFormatManager& rCondFmtMgr    = GetCondFormatManager();
822     XclImpValidationManager& rValidMgr      = GetValidationManager();
823     XclImpPivotTableManager& rPTableMgr     = GetPivotTableManager();
824     XclImpWebQueryBuffer&   rWQBfr          = GetWebQueryBuffer();
825 
826     bool bInUserView = false;           // true = In USERSVIEW(BEGIN|END) record block.
827 
828     enum XclImpReadState
829     {
830         EXC_STATE_BEFORE_GLOBALS,       /// Before workbook globals (wait for initial BOF).
831         EXC_STATE_GLOBALS_PRE,          /// Prefetch for workbook globals.
832         EXC_STATE_GLOBALS,              /// Workbook globals.
833         EXC_STATE_BEFORE_SHEET,         /// Before worksheet (wait for new worksheet BOF).
834         EXC_STATE_SHEET_PRE,            /// Prefetch for worksheet.
835         EXC_STATE_SHEET,                /// Worksheet.
836         EXC_STATE_END                   /// Stop reading.
837     };
838 
839     XclImpReadState eCurrent = EXC_STATE_BEFORE_GLOBALS;
840 
841     ErrCode eLastErr = ERRCODE_NONE;
842 
843     std::unique_ptr< ScfSimpleProgressBar > pProgress( new ScfSimpleProgressBar(
844         aIn.GetSvStreamSize(), GetDocShell(), STR_LOAD_DOC ) );
845 
846     /*  #i104057# Need to track a base position for progress bar calculation,
847         because sheet substreams may not be in order of sheets. */
848     std::size_t nProgressBasePos = 0;
849     std::size_t nProgressBaseSize = 0;
850 
851     bool bSheetHasCodeName = false;
852 
853     std::vector<OUString> aCodeNames;
854     std::vector < SCTAB > nTabsWithNoCodeName;
855 
856     sal_uInt16 nRecId = 0;
857 
858     for (; eCurrent != EXC_STATE_END; mnLastRecId = nRecId)
859     {
860         if( eCurrent == EXC_STATE_BEFORE_SHEET )
861         {
862             sal_uInt16 nScTab = GetCurrScTab();
863             if( nScTab < maSheetOffsets.size() )
864             {
865                 nProgressBaseSize += (maStrm.GetSvStreamPos() - nProgressBasePos);
866                 nProgressBasePos = maSheetOffsets[ nScTab ];
867 
868                 bool bValid = TryStartNextRecord(aIn, nProgressBasePos);
869                 if (!bValid)
870                 {
871                     // Safeguard ourselves from potential infinite loop.
872                     eCurrent = EXC_STATE_END;
873                 }
874 
875                 // import only 256 sheets
876                 if( nScTab > GetScMaxPos().Tab() )
877                 {
878                     if( maStrm.GetRecId() != EXC_ID_EOF )
879                         XclTools::SkipSubStream( maStrm );
880                     // #i29930# show warning box
881                     GetAddressConverter().CheckScTab( nScTab );
882                     eCurrent = EXC_STATE_END;
883                 }
884                 else
885                 {
886                     // #i109800# SHEET record may point to any record inside the
887                     // sheet substream
888                     bool bIsBof = maStrm.GetRecId() == EXC_ID5_BOF;
889                     if( bIsBof )
890                         Bof5(); // read the BOF record
891                     else
892                         pExcRoot->eDateiTyp = Biff8;    // on missing BOF, assume a standard worksheet
893                     NewTable();
894                     switch( pExcRoot->eDateiTyp )
895                     {
896                     case Biff8:     // worksheet
897                     case Biff8M4:   // macro sheet
898                         eCurrent = EXC_STATE_SHEET_PRE;  // Shrfmla Prefetch, Row-Prefetch
899                         // go to next record
900                         if( bIsBof ) maStrm.StartNextRecord();
901                         maStrm.StoreGlobalPosition();
902                         break;
903                     case Biff8C:    // chart sheet
904                         GetCurrSheetDrawing().ReadTabChart( maStrm );
905                         Eof();
906                         GetTracer().TraceChartOnlySheet();
907                         break;
908                     case Biff8W:    // workbook
909                         OSL_FAIL( "ImportExcel8::Read - double workbook globals" );
910                         [[fallthrough]];
911                     case Biff8V:    // VB module
912                     default:
913                         // TODO: do not create a sheet in the Calc document
914                         rD.SetVisible( nScTab, false );
915                         XclTools::SkipSubStream( maStrm );
916                         IncCurrScTab();
917                     }
918                 }
919             }
920             else
921                 eCurrent = EXC_STATE_END;
922         }
923         else
924             aIn.StartNextRecord();
925 
926         if( !aIn.IsValid() )
927         {
928             // #i63591# finalize table if EOF is missing
929             switch( eCurrent )
930             {
931                 case EXC_STATE_SHEET_PRE:
932                     eCurrent = EXC_STATE_SHEET;
933                     aIn.SeekGlobalPosition();
934                     continue;   // next iteration in while loop
935                 case EXC_STATE_SHEET:
936                     Eof();
937                     eCurrent = EXC_STATE_END;
938                 break;
939                 default:
940                     eCurrent = EXC_STATE_END;
941             }
942         }
943 
944         if( eCurrent == EXC_STATE_END )
945             break;
946 
947         if( eCurrent != EXC_STATE_SHEET_PRE && eCurrent != EXC_STATE_GLOBALS_PRE )
948             pProgress->ProgressAbs( nProgressBaseSize + aIn.GetSvStreamPos() - nProgressBasePos );
949 
950         nRecId = aIn.GetRecId();
951 
952         /*  #i39464# Ignore records between USERSVIEWBEGIN and USERSVIEWEND
953             completely (user specific view settings). Otherwise view settings
954             and filters are loaded multiple times, which at least causes
955             problems in auto-filters. */
956         switch( nRecId )
957         {
958             case EXC_ID_USERSVIEWBEGIN:
959                 OSL_ENSURE( !bInUserView, "ImportExcel8::Read - nested user view settings" );
960                 bInUserView = true;
961             break;
962             case EXC_ID_USERSVIEWEND:
963                 OSL_ENSURE( bInUserView, "ImportExcel8::Read - not in user view settings" );
964                 bInUserView = false;
965             break;
966         }
967 
968         if( !bInUserView ) switch( eCurrent )
969         {
970 
971             // before workbook globals: wait for initial workbook globals BOF
972             case EXC_STATE_BEFORE_GLOBALS:
973             {
974                 if( nRecId == EXC_ID5_BOF )
975                 {
976                     OSL_ENSURE( GetBiff() == EXC_BIFF8, "ImportExcel8::Read - wrong BIFF version" );
977                     Bof5();
978                     if( pExcRoot->eDateiTyp == Biff8W )
979                     {
980                         eCurrent = EXC_STATE_GLOBALS_PRE;
981                         maStrm.StoreGlobalPosition();
982                         nBdshtTab = 0;
983                     }
984                     else if( pExcRoot->eDateiTyp == Biff8 )
985                     {
986                         // #i62752# possible to have BIFF8 sheet without globals
987                         NewTable();
988                         eCurrent = EXC_STATE_SHEET_PRE;  // Shrfmla Prefetch, Row-Prefetch
989                         bSheetHasCodeName = false; // reset
990                         aIn.StoreGlobalPosition();
991                     }
992                 }
993             }
994             break;
995 
996             // prefetch for workbook globals
997             case EXC_STATE_GLOBALS_PRE:
998             {
999                 switch( nRecId )
1000                 {
1001                     case EXC_ID_EOF:
1002                     case EXC_ID_EXTSST:
1003                         /*  #i56376# evil hack: if EOF for globals is missing,
1004                             simulate it. This hack works only for the bugdoc
1005                             given in the issue, where the sheet substreams
1006                             start directly after the EXTSST record. A future
1007                             implementation should be more robust against
1008                             missing EOFs. */
1009                         if( (nRecId == EXC_ID_EOF) ||
1010                             ((nRecId == EXC_ID_EXTSST) && (maStrm.GetNextRecId() == EXC_ID5_BOF)) )
1011                         {
1012                             eCurrent = EXC_STATE_GLOBALS;
1013                             aIn.SeekGlobalPosition();
1014                         }
1015                         break;
1016                     case 0x12:  DocProtect(); break;    // PROTECT      [    5678]
1017                     case 0x13:  DocPassword(); break;
1018                     case 0x19:  WinProtection(); break;
1019                     case 0x2F:                          // FILEPASS     [ 2345   ]
1020                         eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
1021                         if( eLastErr != ERRCODE_NONE )
1022                             eCurrent = EXC_STATE_END;
1023                         break;
1024                     case EXC_ID_FILESHARING: ReadFileSharing();         break;
1025                     case 0x3D:  Window1(); break;
1026                     case 0x42:  Codepage(); break;      // CODEPAGE     [ 2345   ]
1027                     case 0x85:  Boundsheet(); break;    // BOUNDSHEET   [    5   ]
1028                     case 0x8C:  Country(); break;       // COUNTRY      [  345   ]
1029 
1030                     // PALETTE follows XFs, but already needed while reading the XFs
1031                     case EXC_ID_PALETTE:        rPal.ReadPalette( maStrm );             break;
1032                 }
1033             }
1034             break;
1035 
1036             // workbook globals
1037             case EXC_STATE_GLOBALS:
1038             {
1039                 switch( nRecId )
1040                 {
1041                     case EXC_ID_EOF:
1042                     case EXC_ID_EXTSST:
1043                         /*  #i56376# evil hack: if EOF for globals is missing,
1044                             simulate it. This hack works only for the bugdoc
1045                             given in the issue, where the sheet substreams
1046                             start directly after the EXTSST record. A future
1047                             implementation should be more robust against
1048                             missing EOFs. */
1049                         if( (nRecId == EXC_ID_EOF) ||
1050                             ((nRecId == EXC_ID_EXTSST) && (maStrm.GetNextRecId() == EXC_ID5_BOF)) )
1051                         {
1052                             rNumFmtBfr.CreateScFormats();
1053                             rXFBfr.CreateUserStyles();
1054                             rPTableMgr.ReadPivotCaches( maStrm );
1055                             rNameMgr.ConvertAllTokens();
1056                             eCurrent = EXC_STATE_BEFORE_SHEET;
1057                         }
1058                     break;
1059                     case 0x0E:  Precision(); break;     // PRECISION
1060                     case 0x22:  Rec1904(); break;       // 1904         [ 2345   ]
1061                     case 0x56:  break;                  // BUILTINFMTCNT[  34    ]
1062                     case 0x8D:  Hideobj(); break;       // HIDEOBJ      [  345   ]
1063                     case 0xD3:  SetHasBasic(); break;
1064                     case 0xDE:  Olesize(); break;
1065 
1066                     case EXC_ID_CODENAME:       ReadCodeName( aIn, true );          break;
1067                     case EXC_ID_USESELFS:       ReadUsesElfs();                     break;
1068 
1069                     case EXC_ID2_FONT:          rFontBfr.ReadFont( maStrm );        break;
1070                     case EXC_ID4_FORMAT:        rNumFmtBfr.ReadFormat( maStrm );    break;
1071                     case EXC_ID5_XF:            rXFBfr.ReadXF( maStrm );            break;
1072                     case EXC_ID_STYLE:          rXFBfr.ReadStyle( maStrm );         break;
1073 
1074                     case EXC_ID_SST:            rSst.ReadSst( maStrm );             break;
1075                     case EXC_ID_TABID:          rTabInfo.ReadTabid( maStrm );       break;
1076                     case EXC_ID_NAME:           rNameMgr.ReadName( maStrm );        break;
1077 
1078                     case EXC_ID_EXTERNSHEET:    rLinkMgr.ReadExternsheet( maStrm ); break;
1079                     case EXC_ID_SUPBOOK:        rLinkMgr.ReadSupbook( maStrm );     break;
1080                     case EXC_ID_XCT:            rLinkMgr.ReadXct( maStrm );         break;
1081                     case EXC_ID_CRN:            rLinkMgr.ReadCrn( maStrm );         break;
1082                     case EXC_ID_EXTERNNAME:     rLinkMgr.ReadExternname( maStrm, pFormConv.get() );  break;
1083 
1084                     case EXC_ID_MSODRAWINGGROUP:rObjMgr.ReadMsoDrawingGroup( maStrm ); break;
1085 
1086                     case EXC_ID_SXIDSTM:        rPTableMgr.ReadSxidstm( maStrm );   break;
1087                     case EXC_ID_SXVS:           rPTableMgr.ReadSxvs( maStrm );      break;
1088                     case EXC_ID_DCONREF:        rPTableMgr.ReadDconref( maStrm );   break;
1089                     case EXC_ID_DCONNAME:       rPTableMgr.ReadDConName( maStrm );  break;
1090                 }
1091 
1092             }
1093             break;
1094 
1095             // prefetch for worksheet
1096             case EXC_STATE_SHEET_PRE:
1097             {
1098                 switch( nRecId )
1099                 {
1100                     // skip chart substream
1101                     case EXC_ID2_BOF:
1102                     case EXC_ID3_BOF:
1103                     case EXC_ID4_BOF:
1104                     case EXC_ID5_BOF:           XclTools::SkipSubStream( maStrm );      break;
1105 
1106                     case EXC_ID_WINDOW2:        rTabViewSett.ReadWindow2( maStrm, false );break;
1107                     case EXC_ID_SCL:            rTabViewSett.ReadScl( maStrm );         break;
1108                     case EXC_ID_PANE:           rTabViewSett.ReadPane( maStrm );        break;
1109                     case EXC_ID_SELECTION:      rTabViewSett.ReadSelection( maStrm );   break;
1110 
1111                     case EXC_ID2_DIMENSIONS:
1112                     case EXC_ID3_DIMENSIONS:    ReadDimensions();                       break;
1113 
1114                     case EXC_ID_CODENAME:       ReadCodeName( aIn, false ); bSheetHasCodeName = true; break;
1115 
1116                     case 0x0A:                          // EOF          [ 2345   ]
1117                     {
1118                         eCurrent = EXC_STATE_SHEET;
1119                         OUString sName;
1120                         GetDoc().GetName( GetCurrScTab(), sName );
1121                         if ( !bSheetHasCodeName )
1122                         {
1123                             nTabsWithNoCodeName.push_back( GetCurrScTab() );
1124                         }
1125                         else
1126                         {
1127                             OUString sCodeName;
1128                             GetDoc().GetCodeName( GetCurrScTab(), sCodeName );
1129                             aCodeNames.push_back( sCodeName );
1130                         }
1131 
1132                         bSheetHasCodeName = false; // reset
1133 
1134                         aIn.SeekGlobalPosition();         // and back to old position
1135                         break;
1136                     }
1137                     case 0x12:  SheetProtect(); break;
1138                     case 0x13:  SheetPassword(); break;
1139                     case 0x42:  Codepage(); break;      // CODEPAGE     [ 2345   ]
1140                     case 0x55:  DefColWidth(); break;
1141                     case 0x7D:  Colinfo(); break;       // COLINFO      [  345   ]
1142                     case 0x81:  Wsbool(); break;        // WSBOOL       [ 2345   ]
1143                     case 0x8C:  Country(); break;       // COUNTRY      [  345   ]
1144                     case 0x99:  Standardwidth(); break; // STANDARDWIDTH[   45   ]
1145                     case 0x9B:  FilterMode(); break;    // FILTERMODE
1146                     case EXC_ID_AUTOFILTERINFO: AutoFilterInfo(); break;// AUTOFILTERINFO
1147                     case EXC_ID_AUTOFILTER: AutoFilter(); break;    // AUTOFILTER
1148                     case 0x0208: Row34(); break;        // ROW          [  34    ]
1149                     case EXC_ID2_ARRAY:
1150                     case EXC_ID3_ARRAY: Array34(); break;      // ARRAY        [  34    ]
1151                     case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[  345   ]
1152                     case 0x0867: FeatHdr(); break;      // FEATHDR
1153                     case 0x0868: Feat(); break;         // FEAT
1154                 }
1155             }
1156             break;
1157 
1158             // worksheet
1159             case EXC_STATE_SHEET:
1160             {
1161                 switch( nRecId )
1162                 {
1163                     // skip unknown substreams
1164                     case EXC_ID2_BOF:
1165                     case EXC_ID3_BOF:
1166                     case EXC_ID4_BOF:
1167                     case EXC_ID5_BOF:           XclTools::SkipSubStream( maStrm );      break;
1168 
1169                     case EXC_ID_EOF:            Eof(); eCurrent = EXC_STATE_BEFORE_SHEET;   break;
1170 
1171                     case EXC_ID2_BLANK:
1172                     case EXC_ID3_BLANK:         ReadBlank();            break;
1173                     case EXC_ID2_INTEGER:       ReadInteger();          break;
1174                     case EXC_ID2_NUMBER:
1175                     case EXC_ID3_NUMBER:        ReadNumber();           break;
1176                     case EXC_ID2_LABEL:
1177                     case EXC_ID3_LABEL:         ReadLabel();            break;
1178                     case EXC_ID2_BOOLERR:
1179                     case EXC_ID3_BOOLERR:       ReadBoolErr();          break;
1180                     case EXC_ID_RK:             ReadRk();               break;
1181 
1182                     case EXC_ID2_FORMULA:
1183                     case EXC_ID3_FORMULA:
1184                     case EXC_ID4_FORMULA:       Formula25();            break;
1185                     case EXC_ID_SHRFMLA:        Shrfmla();              break;
1186                     case 0x000C:    Calccount();            break;  // CALCCOUNT
1187                     case 0x0010:    Delta();                break;  // DELTA
1188                     case 0x0011:    Iteration();            break;  // ITERATION
1189                     case 0x007E:
1190                     case 0x00AE:    Scenman();              break;  // SCENMAN
1191                     case 0x00AF:    Scenario();             break;  // SCENARIO
1192                     case 0x00BD:    Mulrk();                break;  // MULRK        [    5   ]
1193                     case 0x00BE:    Mulblank();             break;  // MULBLANK     [    5   ]
1194                     case 0x00D6:    Rstring();              break;  // RSTRING      [    5   ]
1195                     case 0x00E5:    Cellmerging();          break;  // CELLMERGING
1196                     case 0x00FD:    Labelsst();             break;  // LABELSST     [      8 ]
1197                     case 0x0236:    TableOp();              break;  // TABLE
1198 
1199                     case EXC_ID_HORPAGEBREAKS:
1200                     case EXC_ID_VERPAGEBREAKS:  rPageSett.ReadPageBreaks( maStrm );     break;
1201                     case EXC_ID_HEADER:
1202                     case EXC_ID_FOOTER:         rPageSett.ReadHeaderFooter( maStrm );   break;
1203                     case EXC_ID_LEFTMARGIN:
1204                     case EXC_ID_RIGHTMARGIN:
1205                     case EXC_ID_TOPMARGIN:
1206                     case EXC_ID_BOTTOMMARGIN:   rPageSett.ReadMargin( maStrm );         break;
1207                     case EXC_ID_PRINTHEADERS:   rPageSett.ReadPrintHeaders( maStrm );   break;
1208                     case EXC_ID_PRINTGRIDLINES: rPageSett.ReadPrintGridLines( maStrm ); break;
1209                     case EXC_ID_HCENTER:
1210                     case EXC_ID_VCENTER:        rPageSett.ReadCenter( maStrm );         break;
1211                     case EXC_ID_SETUP:          rPageSett.ReadSetup( maStrm );          break;
1212                     case EXC_ID8_IMGDATA:       rPageSett.ReadImgData( maStrm );        break;
1213 
1214                     case EXC_ID_MSODRAWING:     GetCurrSheetDrawing().ReadMsoDrawing( maStrm ); break;
1215                     // #i61786# weird documents: OBJ without MSODRAWING -> read in BIFF5 format
1216                     case EXC_ID_OBJ:            GetCurrSheetDrawing().ReadObj( maStrm ); break;
1217                     case EXC_ID_NOTE:           GetCurrSheetDrawing().ReadNote( maStrm ); break;
1218 
1219                     case EXC_ID_HLINK:          XclImpHyperlink::ReadHlink( maStrm );   break;
1220                     case EXC_ID_LABELRANGES:    XclImpLabelranges::ReadLabelranges( maStrm ); break;
1221 
1222                     case EXC_ID_CONDFMT:        rCondFmtMgr.ReadCondfmt( maStrm );      break;
1223                     case EXC_ID_CF:             rCondFmtMgr.ReadCF( maStrm );           break;
1224 
1225                     case EXC_ID_DVAL:           XclImpValidationManager::ReadDval( maStrm );  break;
1226                     case EXC_ID_DV:             rValidMgr.ReadDV( maStrm );             break;
1227 
1228                     case EXC_ID_QSI:            rWQBfr.ReadQsi( maStrm );               break;
1229                     case EXC_ID_WQSTRING:       rWQBfr.ReadWqstring( maStrm );          break;
1230                     case EXC_ID_PQRY:           rWQBfr.ReadParamqry( maStrm );          break;
1231                     case EXC_ID_WQSETT:         rWQBfr.ReadWqsettings( maStrm );        break;
1232                     case EXC_ID_WQTABLES:       rWQBfr.ReadWqtables( maStrm );          break;
1233 
1234                     case EXC_ID_SXVIEW:         rPTableMgr.ReadSxview( maStrm );    break;
1235                     case EXC_ID_SXVD:           rPTableMgr.ReadSxvd( maStrm );      break;
1236                     case EXC_ID_SXVI:           rPTableMgr.ReadSxvi( maStrm );      break;
1237                     case EXC_ID_SXIVD:          rPTableMgr.ReadSxivd( maStrm );     break;
1238                     case EXC_ID_SXPI:           rPTableMgr.ReadSxpi( maStrm );      break;
1239                     case EXC_ID_SXDI:           rPTableMgr.ReadSxdi( maStrm );      break;
1240                     case EXC_ID_SXVDEX:         rPTableMgr.ReadSxvdex( maStrm );    break;
1241                     case EXC_ID_SXEX:           rPTableMgr.ReadSxex( maStrm );      break;
1242                     case EXC_ID_SHEETEXT:       rTabViewSett.ReadTabBgColor( maStrm, rPal );    break;
1243                     case EXC_ID_SXVIEWEX9:      rPTableMgr.ReadSxViewEx9( maStrm ); break;
1244                     case EXC_ID_SXADDL:         rPTableMgr.ReadSxAddl( maStrm ); break;
1245                 }
1246             }
1247             break;
1248 
1249             default:;
1250         }
1251     }
1252 
1253     if( eLastErr == ERRCODE_NONE )
1254     {
1255         // In some strange circumstances the codename might be missing
1256         // # Create any missing Sheet CodeNames
1257         for ( const auto& rTab : nTabsWithNoCodeName )
1258         {
1259             SCTAB nTab = 1;
1260             while ( true )
1261             {
1262                 OUString sTmpName = "Sheet" + OUString::number(static_cast<sal_Int32>(nTab++));
1263 
1264                 if ( std::find(aCodeNames.begin(), aCodeNames.end(), sTmpName) == aCodeNames.end() ) // generated codename not found
1265                 {
1266                     // Set new codename
1267                     GetDoc().SetCodeName( rTab, sTmpName );
1268                     // Record newly used codename
1269                     aCodeNames.push_back(sTmpName);
1270                     break;
1271                 }
1272             }
1273         }
1274         // #i45843# Convert pivot tables before calculation, so they are available
1275         // for the GETPIVOTDATA function.
1276         if( GetBiff() == EXC_BIFF8 )
1277             GetPivotTableManager().ConvertPivotTables();
1278 
1279         ScDocumentImport& rDoc = GetDocImport();
1280         rDoc.finalize();
1281         pProgress.reset();
1282 #if 0
1283         // Excel documents look much better without this call; better in the
1284         // sense that the row heights are identical to the original heights in
1285         // Excel.
1286         if ( !rD.IsAdjustHeightLocked())
1287             AdjustRowHeight();
1288 #endif
1289         PostDocLoad();
1290 
1291         rD.CalcAfterLoad(false);
1292 
1293         // import change tracking data
1294         XclImpChangeTrack aImpChTr( GetRoot(), maStrm );
1295         aImpChTr.Apply();
1296 
1297         const XclImpAddressConverter& rAddrConv = GetAddressConverter();
1298         if( rAddrConv.IsTabTruncated() )
1299             eLastErr = SCWARN_IMPORT_SHEET_OVERFLOW;
1300         else if( bTabTruncated || rAddrConv.IsRowTruncated() )
1301             eLastErr = SCWARN_IMPORT_ROW_OVERFLOW;
1302         else if( rAddrConv.IsColTruncated() )
1303             eLastErr = SCWARN_IMPORT_COLUMN_OVERFLOW;
1304 
1305         if( GetBiff() == EXC_BIFF8 )
1306             GetPivotTableManager().MaybeRefreshPivotTables();
1307     }
1308 
1309     return eLastErr;
1310 }
1311 
1312 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1313