LibreOffice Module sc (master)  1
lotimpop.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "lotfilter.hxx"
21 #include <lotimpop.hxx>
22 #include <osl/mutex.hxx>
23 #include <sal/log.hxx>
24 
25 #include <document.hxx>
26 #include <formulacell.hxx>
27 #include <global.hxx>
28 
29 #include <lotfntbf.hxx>
30 #include <lotform.hxx>
31 #include <tool.h>
32 #include <namebuff.hxx>
33 #include <lotattr.hxx>
34 #include <stringutil.hxx>
35 #include <config_fuzzers.h>
36 
37 
38 static osl::Mutex aLotImpSemaphore;
39 
40 ImportLotus::ImportLotus(LotusContext &rContext, SvStream& aStream, rtl_TextEncoding eQ)
41  : ImportTyp(rContext.rDoc, eQ)
42  , pIn(&aStream)
43  , aConv(rContext, *pIn, rContext.rDoc.GetSharedStringPool(), eQ, false)
44  , nTab(0)
45  , nExtTab(0)
46 {
47  // good point to start locking of import lotus
48  aLotImpSemaphore.acquire();
49 }
50 
52 {
53  // no need 4 pLotusRoot anymore
54  aLotImpSemaphore.release();
55 }
56 
58 {
59  sal_uInt16 nFileCode, nFileSub, nSaveCnt;
60  sal_uInt8 nMajorId, nMinorId, nFlags;
61 
62  Read( nFileCode );
63  Read( nFileSub );
64  LotusContext &rContext = aConv.getContext();
65  Read( rContext.aActRange );
66  Read( nSaveCnt );
67  Read( nMajorId );
68  Read( nMinorId );
69  Skip( 1 );
70  Read( nFlags );
71 
72  if( nFileSub == 0x0004 )
73  {
74  if( nFileCode == 0x1000 )
75  {// <= WK3
76  rContext.eFirstType = rContext.eActType = Lotus123Typ::WK3;
77  }
78  else if( nFileCode == 0x1002 )
79  {// WK4
80  rContext.eFirstType = rContext.eActType = Lotus123Typ::WK4;
81  }
82  }
83 }
84 
86 {
87  sal_uInt16 nFileCode, nFileSub;
88 
89  Read( nFileCode );
90  Read( nFileSub );
91 
92  return ( nFileCode == 0x8007 && ( nFileSub == 0x0000 || nFileSub == 0x00001 ) );
93 }
94 
95 void ImportLotus::Columnwidth( sal_uInt16 nRecLen )
96 {
97  SAL_WARN_IF( nRecLen < 4, "sc.filter", "*ImportLotus::Columnwidth(): Record too short!" );
98 
99  sal_uInt8 nLTab, nWindow2;
100  sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 2;
101 
102  Read( nLTab );
103  Read( nWindow2 );
104 
105  if( !rD.HasTable( static_cast<SCTAB> (nLTab) ) )
106  rD.MakeTable( static_cast<SCTAB> (nLTab) );
107 
108  if( nWindow2 )
109  return;
110 
111  Skip( 2 );
112 
113  sal_uInt8 nCol, nSpaces;
114 
115  while( nCnt )
116  {
117  Read( nCol );
118  Read( nSpaces );
119  // Attention: ambiguous Correction factor!
120  rD.SetColWidth( static_cast<SCCOL> (nCol), static_cast<SCTAB> (nLTab), static_cast<sal_uInt16>( TWIPS_PER_CHAR * 1.28 * nSpaces ) );
121 
122  nCnt--;
123  }
124 }
125 
126 void ImportLotus::Hiddencolumn( sal_uInt16 nRecLen )
127 {
128  SAL_WARN_IF( nRecLen < 4, "sc.filter", "*ImportLotus::Hiddencolumn(): Record too short!" );
129 
130  sal_uInt8 nLTab, nWindow2;
131  sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 2;
132 
133  Read( nLTab );
134  Read( nWindow2 );
135 
136  if( nWindow2 )
137  return;
138 
139  Skip( 2 );
140 
141  sal_uInt8 nCol;
142 
143  while( nCnt )
144  {
145  Read( nCol );
146 
147  rD.SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), static_cast<SCTAB>(nLTab), true);
148  nCnt--;
149  }
150 }
151 
153 {
154  sal_uInt16 nRangeType;
155  ScRange aScRange;
156 
157  Read( nRangeType );
158 
159  char aBuffer[ 17 ];
160  pIn->ReadBytes(aBuffer, 16);
161  aBuffer[ 16 ] = 0;
162  OUString aName( aBuffer, strlen(aBuffer), eQuellChar );
163 
164  Read( aScRange );
165 
166  LotusContext &rContext = aConv.getContext();
167  rContext.pRngNmBffWK3->Add( rContext.rDoc, aName, aScRange );
168 }
169 
171 {
172  ScAddress aA;
173 
174  Read( aA );
175 
176  if (!rD.ValidAddress(aA))
177  {
178  SAL_WARN("sc.filter", "invalid address");
179  return;
180  }
181 
182  ScSetStringParam aParam;
183  aParam.setTextInput();
184  rD.EnsureTable(aA.Tab());
185  // coverity[tainted_data : FALSE] - ValidAddress has sanitized aA
186  rD.SetString(aA, "#ERR!", &aParam);
187 }
188 
190 {
191  ScAddress aA;
192 
193  Read( aA );
194 
195  if (!rD.ValidAddress(aA))
196  {
197  SAL_WARN("sc.filter", "invalid address");
198  return;
199  }
200 
201  ScSetStringParam aParam;
202  aParam.setTextInput();
203  rD.EnsureTable(aA.Tab());
204  // coverity[tainted_data : FALSE] - ValidAddress has sanitized aA
205  rD.SetString(aA, "#NA!", &aParam);
206 }
207 
209 {
210  ScAddress aA;
211  OUString aLabel;
212  char cAlign;
213 
214  Read( aA );
215  Read( cAlign );
216  Read( aLabel );
217 
218  if (!rD.ValidAddress(aA))
219  {
220  SAL_WARN("sc.filter", "invalid address");
221  return;
222  }
223 
224  ScSetStringParam aParam;
225  aParam.setTextInput();
226  rD.EnsureTable(aA.Tab());
227  // coverity[tainted_data : FALSE] - ValidAddress has sanitized aA
228  rD.SetString(aA, aLabel, &aParam);
229 }
230 
232 {
233  ScAddress aAddr;
234  double fVal;
235 
236  Read( aAddr );
237  Read( fVal );
238 
239  if (!rD.ValidAddress(aAddr))
240  {
241  SAL_WARN("sc.filter", "invalid address");
242  return;
243  }
244 
245  rD.EnsureTable(aAddr.Tab());
246  // coverity[tainted_data : FALSE] - ValidAddress has sanitized aAddr
247  rD.SetValue(aAddr, fVal);
248 }
249 
251 {
252  ScAddress aAddr;
253  sal_Int16 nVal;
254 
255  Read( aAddr );
256  Read( nVal );
257 
258  if (!rD.ValidAddress(aAddr))
259  {
260  SAL_WARN("sc.filter", "invalid address");
261  return;
262  }
263 
264  rD.EnsureTable(aAddr.Tab());
265  // coverity[tainted_data : FALSE] - ValidAddress has sanitized aAddr
266  rD.SetValue(aAddr, SnumToDouble(nVal));
267 }
268 
269 void ImportLotus::Formulacell( sal_uInt16 n )
270 {
271  SAL_WARN_IF( !pIn, "sc.filter", "-ImportLotus::Formulacell(): Null-Stream!" );
272 
273  ScAddress aAddr;
274 
275  Read( aAddr );
276  Skip( 10 );
277 
278  n -= std::min<sal_uInt16>(n, 14);
279 
280  std::unique_ptr<ScTokenArray> pErg;
281  sal_Int32 nRest = n;
282 
283  aConv.Reset( aAddr );
284  aConv.SetWK3();
285  aConv.Convert( pErg, nRest );
286  if (!aConv.good())
287  return;
288 
289  if (!rD.ValidAddress(aAddr))
290  {
291  SAL_WARN("sc.filter", "invalid address");
292  return;
293  }
294 
295  ScFormulaCell* pCell = pErg ? new ScFormulaCell(rD, aAddr, std::move(pErg)) : new ScFormulaCell(rD, aAddr);
296  pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE );
297  rD.EnsureTable(aAddr.Tab());
298  // coverity[tainted_data : FALSE] - ValidAddress has sanitized aAddr
299  rD.SetFormulaCell(aAddr, pCell);
300 }
301 
302 void ImportLotus::Read( OUString &r )
303 {
305 }
306 
307 void ImportLotus::RowPresentation( sal_uInt16 nRecLen )
308 {
309  SAL_WARN_IF( nRecLen < 5, "sc.filter", "*ImportLotus::RowPresentation(): Record too short!" );
310 
311  sal_uInt8 nLTab, nFlags;
312  sal_uInt16 nRow, nHeight;
313  sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 8;
314 
315  Read( nLTab );
316  Skip( 1 );
317 
318  while( nCnt )
319  {
320  Read( nRow );
321  Read( nHeight );
322  Skip( 2 );
323  Read( nFlags );
324  Skip( 1 );
325 
326  if( nFlags & 0x02 ) // Fixed / Stretch to fit fonts
327  { // fixed
328  // Height in Lotus in 1/32 Points
329  nHeight *= 20; // -> 32 * TWIPS
330  nHeight /= 32; // -> TWIPS
331 
332  rD.SetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), rD.GetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab) ) | CRFlags::ManualSize );
333 
334  rD.SetRowHeight( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), nHeight );
335  }
336 
337  nCnt--;
338  }
339 }
340 
342 {
343  sal_uInt16 nTmpTab(0);
344  Read(nTmpTab);
345  OUString aName;
346  Read(aName);
347 
348  SCTAB nLTab(SanitizeTab(static_cast<SCTAB>(nTmpTab)));
349 #if ENABLE_FUZZERS
350  //ofz#14167 arbitrary sheet limit to make fuzzing useful
351  if (nLTab > 5)
352  nLTab = 5;
353 #endif
354 
355  if (rD.HasTable(nLTab))
356  rD.RenameTab(nLTab, aName);
357  else
358  rD.InsertTab(nLTab, aName);
359 }
360 
362 {
363  sal_uInt8 nNum;
364  OUString aName;
365 
366  Read( nNum );
367 
368  if( nNum >= LotusFontBuffer::nSize )
369  return; // nonsense
370 
371  Read( aName );
372 
373  LotusContext &rContext = aConv.getContext();
374  rContext.maFontBuff.SetName( nNum, aName );
375 }
376 
378 {
379  LotusContext &rContext = aConv.getContext();
380  for( sal_uInt16 nCnt = 0 ; nCnt < LotusFontBuffer::nSize ; nCnt++ )
381  {
382  sal_uInt16 nType;
383  Read( nType );
384  rContext.maFontBuff.SetType( nCnt, nType );
385  }
386 }
387 
389 {
390  LotusContext &rContext = aConv.getContext();
391  for( sal_uInt16 nCnt = 0 ; nCnt < LotusFontBuffer::nSize ; nCnt++ )
392  {
393  sal_uInt16 nSize;
394  Read( nSize );
395  rContext.maFontBuff.SetHeight( nCnt, nSize );
396  }
397 }
398 
399 void ImportLotus::Row_( const sal_uInt16 nRecLen )
400 {
401  SAL_WARN_IF( nExtTab < 0, "sc.filter", "*ImportLotus::Row_(): not possible!" );
402 
403  sal_uInt16 nCntDwn = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 5;
404  SCCOL nColCnt = 0;
405  sal_uInt8 nRepeats;
406  LotAttrWK3 aAttr;
407 
408  bool bCenter = false;
409  SCCOL nCenterStart = 0, nCenterEnd = 0;
410  LotusContext &rContext = aConv.getContext();
411 
412  sal_uInt16 nTmpRow(0);
413  Read(nTmpRow);
414  SCROW nRow(rContext.rDoc.SanitizeRow(static_cast<SCROW>(nTmpRow)));
415  sal_uInt16 nHeight(0);
416  Read(nHeight);
417 
418  nHeight &= 0x0FFF;
419  nHeight *= 22;
420 
421  SCTAB nDestTab(static_cast<SCTAB>(nExtTab));
422 
423  if( nHeight )
424  rD.SetRowHeight(nRow, nDestTab, nHeight);
425 
426  while( nCntDwn )
427  {
428  Read( aAttr );
429  Read( nRepeats );
430 
431  if( aAttr.HasStyles() )
432  rContext.maAttrTable.SetAttr(
433  rContext, nColCnt, static_cast<SCCOL> ( nColCnt + nRepeats ), nRow, aAttr );
434 
435  // Do this here and NOT in class LotAttrTable, as we only add attributes if the other
436  // attributes are set
437  // -> for Center-Attribute default is centered
438  if( aAttr.IsCentered() )
439  {
440  if( bCenter )
441  {
442  if (rD.HasData(nColCnt, nRow, nDestTab))
443  {
444  // new Center after previous Center
445  rD.DoMerge(nDestTab, nCenterStart, nRow, nCenterEnd, nRow);
446  nCenterStart = nColCnt;
447  }
448  }
449  else
450  {
451  // fully new Center
452  bCenter = true;
453  nCenterStart = nColCnt;
454  }
455  nCenterEnd = nColCnt + static_cast<SCCOL>(nRepeats);
456  }
457  else
458  {
459  if( bCenter )
460  {
461  // possibly reset old Center
462  rD.DoMerge(nDestTab, nCenterStart, nRow, nCenterEnd, nRow);
463  bCenter = false;
464  }
465  }
466 
467  nColCnt = nColCnt + static_cast<SCCOL>(nRepeats);
468  nColCnt++;
469 
470  nCntDwn--;
471  }
472 
473  if( bCenter )
474  // possibly reset old Center
475  rD.DoMerge(nDestTab, nCenterStart, nRow, nCenterEnd, nRow);
476 }
477 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static void AppendCString(SvStream &rStrm, OUString &rString, rtl_TextEncoding eTextEnc)
Appends a zero terminated byte string.
Definition: ftools.cxx:273
void NamedSheet()
Definition: lotimpop.cxx:341
void Font_Ysize()
Definition: lotimpop.cxx:388
Store parameters used in the ScDocument::SetString() method.
Definition: stringutil.hxx:34
ScRange aActRange
Definition: lotfilter.hxx:54
void setTextInput()
Call this whenever you need to unconditionally set input as text, no matter what the input is...
Definition: stringutil.cxx:37
virtual ~ImportLotus() override
Definition: lotimpop.cxx:51
SC_DLLPUBLIC void SetColHidden(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bHidden)
Definition: document.cxx:4517
void Row_(const sal_uInt16 nRecLen)
Definition: lotimpop.cxx:399
double SnumToDouble(sal_Int16 nVal)
Definition: tool.cxx:103
void Skip(const sal_uInt16 nNumBytes)
Definition: lotimpop.hxx:131
void RowPresentation(sal_uInt16 nRecLen)
Definition: lotimpop.cxx:307
SC_DLLPUBLIC void SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
Definition: document.cxx:3508
LotAttrTable maAttrTable
Definition: lotfilter.hxx:57
#define TWIPS_PER_CHAR
Definition: global.hxx:90
ScDocument & rDoc
Definition: lotfilter.hxx:44
void Reset(const ScAddress &rEingPos)
Definition: lotform.cxx:356
void Nacell()
Definition: lotimpop.cxx:189
void Userrange()
Definition: lotimpop.cxx:152
std::unique_ptr< RangeNameBufferWK3 > pRngNmBffWK3
Definition: lotfilter.hxx:55
ScDocument & rD
Definition: imp_op.hxx:46
void Formulacell(sal_uInt16 nRecLen)
Definition: lotimpop.cxx:269
SC_DLLPUBLIC bool RenameTab(SCTAB nTab, const OUString &rName, bool bExternalDocument=false)
Definition: document.cxx:852
SC_DLLPUBLIC void SetColWidth(SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth)
Definition: document.cxx:4133
void SetName(const sal_uInt16 nIndex, const OUString &rName)
Definition: fontbuff.cxx:70
rtl_TextEncoding eQuellChar
Definition: imp_op.hxx:45
void Numbercell()
Definition: lotimpop.cxx:231
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
Definition: document.cxx:190
SCTAB Tab() const
Definition: address.hxx:270
SC_DLLPUBLIC bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
Definition: document.cxx:3413
static const sal_uInt16 nSize
Definition: lotfntbf.hxx:50
ImportLotus(LotusContext &rContext, SvStream &, rtl_TextEncoding eSrc)
Definition: lotimpop.cxx:40
void Font_Type()
Definition: lotimpop.cxx:377
void Labelcell()
Definition: lotimpop.cxx:208
bool HasStyles() const
Definition: lotattr.hxx:42
sal_Int16 SCCOL
Definition: types.hxx:21
void Bof()
Definition: lotimpop.cxx:57
SvStream * pIn
Definition: lotimpop.hxx:34
SC_DLLPUBLIC void SetRowHeight(SCROW nRow, SCTAB nTab, sal_uInt16 nNewHeight)
Definition: document.cxx:4145
SC_DLLPUBLIC bool InsertTab(SCTAB nPos, const OUString &rName, bool bExternalDocument=false, bool bUndoDeleteTab=false)
Definition: document.cxx:503
bool BofFm3()
Definition: lotimpop.cxx:85
void Hiddencolumn(sal_uInt16 nRecLen)
Definition: lotimpop.cxx:126
void Smallnumcell()
Definition: lotimpop.cxx:250
SC_DLLPUBLIC void DoMerge(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool bDeleteCaptions=true)
Definition: documen3.cxx:2068
bool IsCentered() const
Definition: lotattr.hxx:48
bool ValidAddress(const ScAddress &rAddress) const
Definition: document.hxx:878
void Font_Face()
Definition: lotimpop.cxx:361
SC_DLLPUBLIC void EnsureTable(SCTAB nTab)
Definition: documen2.cxx:539
std::size_t ReadBytes(void *pData, std::size_t nSize)
LotusFontBuffer maFontBuff
Definition: lotfilter.hxx:56
SCROW SanitizeRow(SCROW nRow) const
Definition: document.hxx:880
virtual void Convert(std::unique_ptr< ScTokenArray > &rpErg, sal_Int32 &nRest) override
Definition: lotform.cxx:384
SCTAB SanitizeTab(SCTAB nTab)
Definition: address.hxx:138
sal_Int32 SCROW
Definition: types.hxx:17
void SetType(const sal_uInt16 nIndex, const sal_uInt16 nType)
Definition: fontbuff.cxx:90
std::unique_ptr< char[]> aBuffer
SC_DLLPUBLIC ScFormulaCell * SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell)
Set formula cell, and transfer its ownership to the document.
Definition: documen2.cxx:1083
ErrCode Read()
Definition: lotread.cxx:226
Lotus123Typ eActType
Definition: lotfilter.hxx:53
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
OUString aName
sal_Int32 nExtTab
Definition: lotimpop.hxx:37
void SetWK3()
Definition: lotform.hxx:109
SC_DLLPUBLIC bool HasData(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: documen5.cxx:526
OUString aLabel
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:400
bool good() const
Definition: formel.hxx:125
Lotus123Typ eFirstType
Definition: lotfilter.hxx:52
static osl::Mutex aLotImpSemaphore
Definition: lotimpop.cxx:38
LotusContext & getContext()
Definition: lotform.hxx:94
#define SAL_WARN(area, stream)
SC_DLLPUBLIC void MakeTable(SCTAB nTab, bool _bNeedsNameCheck=true)
Definition: document.cxx:167
SC_DLLPUBLIC void SetRowFlags(SCROW nRow, SCTAB nTab, CRFlags nNewFlags)
Definition: document.cxx:4366
void SetAttr(LotusContext &rContext, const SCCOL nColFirst, const SCCOL nColLast, const SCROW nRow, const LotAttrWK3 &)
Definition: lotattr.cxx:230
void AddRecalcMode(ScRecalcMode)
void SetHeight(const sal_uInt16 nIndex, const sal_uInt16 nHeight)
Definition: fontbuff.cxx:83
LotusToSc aConv
Definition: lotimpop.hxx:35
void Errcell()
Definition: lotimpop.cxx:170
sal_Int16 SCTAB
Definition: types.hxx:22
SC_DLLPUBLIC CRFlags GetRowFlags(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4386
void Columnwidth(sal_uInt16 nRecLen)
Definition: lotimpop.cxx:95