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