LibreOffice Module sc (master) 1
op.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 <rtl/math.hxx>
21#include <rtl/character.hxx>
22
23#include <string.h>
24
25#include <scitems.hxx>
26#include <patattr.hxx>
27#include <docpool.hxx>
28#include <editeng/postitem.hxx>
29#include <editeng/udlnitem.hxx>
30#include <editeng/wghtitem.hxx>
33
34#include <formulacell.hxx>
35#include <document.hxx>
36#include <postit.hxx>
37
38#include <op.h>
39#include <optab.h>
40#include <tool.h>
41#include "lotfilter.hxx"
42#include <lotform.hxx>
43#include <lotrange.hxx>
44#include <ftools.hxx>
45
46#include <vector>
47#include <map>
48#include <memory>
49
50static sal_uInt16 nDefWidth = sal_uInt16( TWIPS_PER_CHAR * 10 );
51
52void NI(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 n)
53{
54 r.SeekRel( n );
55}
56
57void OP_BOF(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 /*n*/)
58{
59 r.SeekRel( 2 ); // skip version number
60}
61
62void OP_EOF(LotusContext& rContext, SvStream& /*r*/, sal_uInt16 /*n*/)
63{
64 rContext.bEOF = true;
65}
66
67void OP_Integer(LotusContext& rContext, SvStream& r, sal_uInt16 /*n*/)
68{
69 sal_uInt8 nFormat(0);
70 sal_uInt16 nTmpCol(0), nTmpRow(0);
71 sal_Int16 nValue(0);
72 r.ReadUChar(nFormat).ReadUInt16(nTmpCol).ReadUInt16(nTmpRow).ReadInt16(nValue);
73 SCCOL nCol(static_cast<SCCOL>(nTmpCol));
74 SCROW nRow(static_cast<SCROW>(nTmpRow));
75
76 ScAddress aAddr(nCol, nRow, 0);
77 if (rContext.rDoc.ValidAddress(aAddr))
78 {
79 rContext.rDoc.EnsureTable(0);
80 // coverity[tainted_data : FALSE] - ValidAddress has sanitized aAddr
81 rContext.rDoc.SetValue(aAddr, static_cast<double>(nValue));
82
83 // 0 digits in fractional part!
84 SetFormat(rContext, nCol, nRow, 0, nFormat, 0);
85 }
86}
87
88void OP_Number(LotusContext& rContext, SvStream& r, sal_uInt16 /*n*/)
89{
90 sal_uInt8 nFormat(0);
91 sal_uInt16 nTmpCol(0), nTmpRow(0);
92 double fValue(0.0);
93 r.ReadUChar( nFormat ).ReadUInt16(nTmpCol).ReadUInt16(nTmpRow).ReadDouble(fValue);
94 SCCOL nCol(static_cast<SCCOL>(nTmpCol));
95 SCROW nRow(static_cast<SCROW>(nTmpRow));
96
97 ScAddress aAddr(nCol, nRow, 0);
98 if (rContext.rDoc.ValidAddress(aAddr))
99 {
100 fValue = ::rtl::math::round( fValue, 15 );
101 rContext.rDoc.EnsureTable(0);
102 // coverity[tainted_data : FALSE] - ValidAddress has sanitized aAddr
103 rContext.rDoc.SetValue(aAddr, fValue);
104
105 SetFormat(rContext, nCol, nRow, 0, nFormat, nFractionalFloat);
106 }
107}
108
109void OP_Label(LotusContext& rContext, SvStream& r, sal_uInt16 n)
110{
111 sal_uInt8 nFormat(0);
112 sal_uInt16 nTmpCol(0), nTmpRow(0);
113 r.ReadUChar(nFormat).ReadUInt16(nTmpCol).ReadUInt16(nTmpRow);
114 SCCOL nCol(static_cast<SCCOL>(nTmpCol));
115 SCROW nRow(static_cast<SCROW>(nTmpRow));
116
117 n -= std::min<sal_uInt16>(n, 5);
118
119 std::vector<char> aText(n + 1);
120 n = r.ReadBytes(aText.data(), n);
121 aText[n] = 0;
122
123 if (rContext.rDoc.ValidColRow(nCol, nRow))
124 {
125 nFormat &= 0x80; // don't change Bit 7
126 nFormat |= 0x75; // protected does not matter, special-text is set
127
128 PutFormString(rContext, nCol, nRow, 0, aText.data());
129
130 SetFormat(rContext, nCol, nRow, 0, nFormat, nFractionalStd);
131 }
132}
133
134void OP_Formula(LotusContext &rContext, SvStream& r, sal_uInt16 /*n*/)
135{
136 sal_uInt8 nFormat(0);
137 sal_uInt16 nTmpCol(0), nTmpRow(0);
138 r.ReadUChar(nFormat).ReadUInt16(nTmpCol).ReadUInt16(nTmpRow);
139 r.SeekRel(8); // skip result
140 sal_uInt16 nFormulaSize(0);
141 r.ReadUInt16(nFormulaSize);
142
143 SCCOL nCol(static_cast<SCCOL>(nTmpCol));
144 SCROW nRow(static_cast<SCROW>(nTmpRow));
145
146 std::unique_ptr<ScTokenArray> pResult;
147 sal_Int32 nBytesLeft = nFormulaSize;
148 ScAddress aAddress(nCol, nRow, 0);
149
151 LotusToSc aConv(rContext, r, rSPool, rContext.eCharset, false);
152 aConv.Reset( aAddress );
153 aConv.Convert( pResult, nBytesLeft );
154 if (!aConv.good())
155 return;
156
157 if (rContext.rDoc.ValidColRow(nCol, nRow))
158 {
159 ScFormulaCell* pCell = new ScFormulaCell(rContext.rDoc, aAddress, std::move(pResult));
160 pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE );
161 rContext.rDoc.EnsureTable(0);
162 // coverity[tainted_data : FALSE] - ValidColRow has sanitized aAddr
163 rContext.rDoc.SetFormulaCell(ScAddress(nCol, nRow, 0), pCell);
164
165 // nFormat = Default -> number of digits in fractional part like Float
166 SetFormat(rContext, nCol, nRow, 0, nFormat, nFractionalFloat);
167 }
168}
169
170void OP_ColumnWidth(LotusContext& rContext, SvStream& r, sal_uInt16 /*n*/)
171{
172 sal_uInt16 nTmpCol(0);
173 sal_uInt8 nWidthSpaces(0);
174 r.ReadUInt16(nTmpCol).ReadUChar(nWidthSpaces);
175 SCCOL nCol(static_cast<SCCOL>(nTmpCol));
176
177 if (!rContext.rDoc.ValidCol(nCol))
178 return;
179
180 nCol = rContext.rDoc.SanitizeCol(nCol);
181
182 sal_uInt16 nBreite;
183 if( nWidthSpaces )
184 // assuming 10cpi character set
185 nBreite = static_cast<sal_uInt16>( TWIPS_PER_CHAR * nWidthSpaces );
186 else
187 {
188 rContext.rDoc.SetColHidden(nCol, nCol, 0, true);
189 nBreite = nDefWidth;
190 }
191
192 rContext.rDoc.SetColWidth(nCol, 0, nBreite);
193}
194
195void OP_NamedRange(LotusContext& rContext, SvStream& r, sal_uInt16 /*n*/)
196{
197 // POST: don't save for invalid coordinates
198 sal_uInt16 nColSt, nRowSt, nColEnd, nRowEnd;
199
200 char cBuffer[ 16+1 ];
201 r.ReadBytes(cBuffer, 16);
202 cBuffer[ 16 ] = 0;
203
204 r.ReadUInt16( nColSt ).ReadUInt16( nRowSt ).ReadUInt16( nColEnd ).ReadUInt16( nRowEnd );
205
206 if (!r.good())
207 return;
208
209 if (!rContext.rDoc.ValidColRow(static_cast<SCCOL>(nColSt), nRowSt) || !rContext.rDoc.ValidColRow(static_cast<SCCOL>(nColEnd), nRowEnd))
210 return;
211
212 std::unique_ptr<LotusRange> pRange;
213
214 if( nColSt == nColEnd && nRowSt == nRowEnd )
215 pRange.reset(new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt) ));
216 else
217 pRange.reset(new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt),
218 static_cast<SCCOL> (nColEnd), static_cast<SCROW> (nRowEnd) ));
219
220 char cBuf[sizeof(cBuffer)+1];
221 if( rtl::isAsciiDigit( static_cast<unsigned char>(*cBuffer) ) )
222 { // first char in name is a number -> prepend 'A'
223 cBuf[0] = 'A';
224 strcpy( cBuf + 1, cBuffer ); // #100211# - checked
225 }
226 else
227 strcpy( cBuf, cBuffer ); // #100211# - checked
228
229 OUString aTmp( cBuf, strlen(cBuf), rContext.eCharset );
230
232
233 rContext.maRangeNames.Append( &rContext.rDoc, std::move(pRange) );
234}
235
236void OP_SymphNamedRange(LotusContext& rContext, SvStream& r, sal_uInt16 /*n*/)
237{
238 // POST:don't save for invalid coordinates
239 sal_uInt16 nColSt, nRowSt, nColEnd, nRowEnd;
241
242 char cBuffer[ 16+1 ];
243 r.ReadBytes(cBuffer, 16);
244 cBuffer[ 16 ] = 0;
245
246 r.ReadUInt16( nColSt ).ReadUInt16( nRowSt ).ReadUInt16( nColEnd ).ReadUInt16( nRowEnd ).ReadUChar( nType );
247
248 if (!r.good())
249 return;
250
251 if (!rContext.rDoc.ValidColRow(static_cast<SCCOL>(nColSt), nRowSt) || !rContext.rDoc.ValidColRow(static_cast<SCCOL>(nColEnd), nRowEnd))
252 return;
253
254 std::unique_ptr<LotusRange> pRange;
255
256 if( nType )
257 pRange.reset(new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt) ));
258 else
259 pRange.reset(new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt),
260 static_cast<SCCOL> (nColEnd), static_cast<SCROW> (nRowEnd) ));
261
262 char cBuf[sizeof(cBuffer)+1];
263 if( rtl::isAsciiDigit( static_cast<unsigned char>(*cBuffer) ) )
264 { // first char in name is a number -> prepend 'A'
265 cBuf[0] = 'A';
266 strcpy( cBuf + 1, cBuffer ); // #100211# - checked
267 }
268 else
269 strcpy( cBuf, cBuffer ); // #100211# - checked
270
271 OUString aTmp( cBuf, strlen(cBuf), rContext.eCharset );
273
274 rContext.maRangeNames.Append( &rContext.rDoc, std::move(pRange) );
275}
276
277void OP_Footer(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 n)
278{
279 r.SeekRel( n );
280}
281
282void OP_Header(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 n)
283{
284 r.SeekRel( n );
285}
286
287void OP_Margins(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 n)
288{
289 r.SeekRel( n );
290}
291
292void OP_HiddenCols(LotusContext& rContext, SvStream& r, sal_uInt16 /*n*/)
293{
294 SCCOL nCount = 0;
295 for (sal_uInt16 nByte = 0; nByte < 32; ++nByte) // 32 Bytes with ...
296 {
297 sal_uInt8 nCurrent(0);
298 r.ReadUChar(nCurrent);
299 for (sal_uInt16 nBit = 0; nBit < 8; ++nBit) // ...each 8 Bits = 256 Bits
300 {
301 if( nCurrent & 0x01 ) // is lowest Bit set?
302 {
303 // -> Hidden Col
304 rContext.rDoc.SetColHidden(nCount, nCount, 0, true);
305 }
306
307 nCount++;
308 nCurrent = nCurrent / 2; // the next please...
309 }
310 }
311}
312
313void OP_Window1(LotusContext& rContext, SvStream& r, sal_uInt16 n)
314{
315 r.SeekRel( 4 ); // skip Cursor Pos
316
317 sal_uInt8 nDefaultFormat; // -> op.cpp, standard cell format
318 r.ReadUChar(nDefaultFormat);
319
320 r.SeekRel( 1 ); // skip 'unused'
321
323 if (!r.good())
324 return;
325
326 r.SeekRel( n - 8 ); // skip the rest
327
328 nDefWidth = static_cast<sal_uInt16>( TWIPS_PER_CHAR * nDefWidth );
329
330 const bool bFuzzing = utl::ConfigManager::IsFuzzing();
331
332 // instead of default, set all Cols in SC by hand
333 for (SCCOL nCol = 0 ; nCol <= rContext.rDoc.MaxCol() ; nCol++)
334 {
335 rContext.rDoc.SetColWidth( nCol, 0, nDefWidth );
336 if (bFuzzing)
337 break;
338 }
339}
340
341void OP_Blank(LotusContext& rContext, SvStream& r, sal_uInt16 /*n*/)
342{
343 sal_uInt8 nFormat(0);
344 sal_uInt16 nTmpCol(0), nTmpRow(0);
345 r.ReadUChar( nFormat ).ReadUInt16(nTmpCol).ReadUInt16(nTmpRow);
346 SCCOL nCol(static_cast<SCCOL>(nTmpCol));
347 SCROW nRow(static_cast<SCROW>(nTmpRow));
348
349 SetFormat(rContext, nCol, nRow, 0, nFormat, nFractionalFloat);
350}
351
352void OP_BOF123(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 /*n*/)
353{
354 r.SeekRel( 26 );
355}
356
357void OP_EOF123(LotusContext& rContext, SvStream& /*r*/, sal_uInt16 /*n*/)
358{
359 rContext.bEOF = true;
360}
361
362void OP_Label123(LotusContext& rContext, SvStream& r, sal_uInt16 n)
363{
364 sal_uInt8 nTmpTab(0), nTmpCol(0);
365 sal_uInt16 nTmpRow(0);
366 r.ReadUInt16(nTmpRow).ReadUChar(nTmpTab).ReadUChar(nTmpCol);
367 SCTAB nTab(static_cast<SCTAB>(nTmpTab));
368 SCCOL nCol(static_cast<SCCOL>(nTmpCol));
369 SCROW nRow(static_cast<SCROW>(nTmpRow));
370
371 n -= std::min<sal_uInt16>(n, 4);
372
373 std::unique_ptr<char[]> pText(new char[n + 1]);
374 r.ReadBytes(pText.get(), n);
375 pText[ n ] = 0;
376
377 PutFormString(rContext, nCol, nRow, nTab, pText.get());
378}
379
380void OP_Number123(LotusContext& rContext, SvStream& r, sal_uInt16 /*n*/)
381{
382 sal_uInt16 nTmpRow(0);
383 sal_uInt8 nTmpCol(0), nTmpTab(0);
384 sal_uInt32 nValue(0);
385 r.ReadUInt16(nTmpRow).ReadUChar(nTmpTab).ReadUChar(nTmpCol).ReadUInt32(nValue);
386 SCTAB nTab(static_cast<SCTAB>(nTmpTab));
387 SCCOL nCol(static_cast<SCCOL>(nTmpCol));
388 SCROW nRow(static_cast<SCROW>(nTmpRow));
389
390 ScAddress aAddr(nCol, nRow, nTab);
391 if (rContext.rDoc.ValidAddress(aAddr) && nTab <= rContext.rDoc.GetMaxTableNumber())
392 {
393 double fValue = Snum32ToDouble( nValue );
394 rContext.rDoc.EnsureTable(nTab);
395 // coverity[tainted_data : FALSE] - ValidAddress has sanitized aAddr
396 rContext.rDoc.SetValue(aAddr, fValue);
397 }
398}
399
400void OP_Formula123(LotusContext& rContext, SvStream& r, sal_uInt16 n)
401{
402 sal_uInt16 nTmpRow(0);
403 sal_uInt8 nTmpCol(0), nTmpTab(0);
404 r.ReadUInt16(nTmpRow).ReadUChar(nTmpTab).ReadUChar(nTmpCol);
405 SCTAB nTab(static_cast<SCTAB>(nTmpTab));
406 SCCOL nCol(static_cast<SCCOL>(nTmpCol));
407 SCROW nRow(static_cast<SCROW>(nTmpRow));
408 r.SeekRel( 8 ); // skip Result
409
410 std::unique_ptr<ScTokenArray> pResult;
411 sal_Int32 nBytesLeft = (n > 12) ? n - 12 : 0;
412 ScAddress aAddress(nCol, nRow, nTab);
413
415 LotusToSc aConv(rContext, r, rSPool, rContext.eCharset, true);
416 aConv.Reset( aAddress );
417 aConv.Convert( pResult, nBytesLeft );
418 if (!aConv.good())
419 return;
420
421 if (rContext.rDoc.ValidAddress(aAddress) && nTab <= rContext.rDoc.GetMaxTableNumber())
422 {
423 ScFormulaCell* pCell = new ScFormulaCell(rContext.rDoc, aAddress, std::move(pResult));
424 pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE );
425 rContext.rDoc.EnsureTable(nTab);
426 // coverity[tainted_data : FALSE] - ValidAddress has sanitized aAddr
427 rContext.rDoc.SetFormulaCell(aAddress, pCell);
428 }
429}
430
431void OP_IEEENumber123(LotusContext& rContext, SvStream& r, sal_uInt16 /*n*/)
432{
433 sal_uInt16 nTmpRow(0);
434 sal_uInt8 nTmpCol(0), nTmpTab(0);
435 double dValue(0.0);
436 r.ReadUInt16(nTmpRow).ReadUChar(nTmpTab).ReadUChar(nTmpCol).ReadDouble(dValue);
437 SCTAB nTab(static_cast<SCTAB>(nTmpTab));
438 SCCOL nCol(static_cast<SCCOL>(nTmpCol));
439 SCROW nRow(static_cast<SCROW>(nTmpRow));
440
441 ScAddress aAddr(nCol, nRow, nTab);
442 if (rContext.rDoc.ValidAddress(aAddr) && nTab <= rContext.rDoc.GetMaxTableNumber())
443 {
444 rContext.rDoc.EnsureTable(nTab);
445 // coverity[tainted_data : FALSE] - ValidAddress has sanitized aAddr
446 rContext.rDoc.SetValue(aAddr, dValue);
447 }
448}
449
450void OP_Note123(LotusContext& rContext, SvStream& r, sal_uInt16 n)
451{
452 sal_uInt16 nTmpRow(0);
453 sal_uInt8 nTmpTab(0), nTmpCol(0);
454 r.ReadUInt16(nTmpRow).ReadUChar(nTmpTab).ReadUChar(nTmpCol);
455 SCTAB nTab(static_cast<SCTAB>(nTmpTab));
456 SCCOL nCol(static_cast<SCCOL>(nTmpCol));
457 SCROW nRow(static_cast<SCROW>(nTmpRow));
458
459 n -= std::min<sal_uInt16>(n, 4);
460
461 std::unique_ptr<char[]> pText(new char[n + 1]);
462 r.ReadBytes(pText.get(), n);
463 pText[ n ] = 0;
464
465 OUString aNoteText(pText.get(), strlen(pText.get()), rContext.eCharset);
466 pText.reset();
467
468 ScAddress aPos(nCol, nRow, nTab);
469 ScNoteUtil::CreateNoteFromString( rContext.rDoc, aPos, aNoteText, false, false );
470}
471
472void OP_HorAlign123(LotusContext& /*rContext*/, sal_uInt8 nAlignPattern, SfxItemSet& rPatternItemSet)
473{
474// pre: Pattern is stored in the last 3 bites of the 21st byte
475// post: Appropriate Horizontal Alignment is set in rPattern according to the bit pattern.
476//
477// LEFT:001, RIGHT:010, CENTER:011, JUSTIFY:110,
478// LEFT-Text/RIGHT-NUMBER:100, DEFAULT:000
479
480 nAlignPattern = ( nAlignPattern & 0x07);
481
482 switch (nAlignPattern)
483 {
484 case 1:
485 rPatternItemSet.Put( SvxHorJustifyItem( SvxCellHorJustify::Left, ATTR_HOR_JUSTIFY ) );
486 break;
487 case 2:
488 rPatternItemSet.Put( SvxHorJustifyItem( SvxCellHorJustify::Right, ATTR_HOR_JUSTIFY ) );
489 break;
490 case 3:
491 rPatternItemSet.Put( SvxHorJustifyItem( SvxCellHorJustify::Center, ATTR_HOR_JUSTIFY) );
492 break;
493 case 4:
494 rPatternItemSet.Put( SvxHorJustifyItem( SvxCellHorJustify::Standard, ATTR_HOR_JUSTIFY ) );
495 break;
496 case 6:
497 rPatternItemSet.Put( SvxHorJustifyItem( SvxCellHorJustify::Block, ATTR_HOR_JUSTIFY ) );
498 break;
499 default:
500 rPatternItemSet.Put( SvxHorJustifyItem( SvxCellHorJustify::Standard, ATTR_HOR_JUSTIFY ) );
501 break;
502 }
503}
504
505void OP_VerAlign123(LotusContext& /*rContext*/, sal_uInt8 nAlignPattern, SfxItemSet& rPatternItemSet)
506{
507// pre: Pattern is stored in the last 3 bites of the 22nd byte
508// post: Appropriate Vertical Alignment is set in rPattern according to the bit pattern.
509//
510// TOP:001, MIDDLE:010, DOWN:100, DEFAULT:000
511
512 nAlignPattern = ( nAlignPattern & 0x07);
513
514 switch (nAlignPattern)
515 {
516 case 0:
517 rPatternItemSet.Put( SvxVerJustifyItem(SvxCellVerJustify::Standard, ATTR_VER_JUSTIFY) );
518 break;
519 case 1:
520 rPatternItemSet.Put( SvxVerJustifyItem(SvxCellVerJustify::Top, ATTR_VER_JUSTIFY) );
521 break;
522 case 2:
523 rPatternItemSet.Put( SvxVerJustifyItem(SvxCellVerJustify::Center, ATTR_VER_JUSTIFY) );
524 break;
525 case 4:
526 rPatternItemSet.Put( SvxVerJustifyItem(SvxCellVerJustify::Bottom, ATTR_VER_JUSTIFY) );
527 break;
528 default:
529 rPatternItemSet.Put( SvxVerJustifyItem(SvxCellVerJustify::Standard, ATTR_VER_JUSTIFY) );
530 break;
531 }
532}
533
534void OP_CreatePattern123(LotusContext& rContext, SvStream& r, sal_uInt16 n)
535{
536 sal_uInt16 nCode;
537
538 ScPatternAttr aPattern(rContext.rDoc.GetPool());
539 SfxItemSet& rItemSet = aPattern.GetItemSet();
540
541 r.ReadUInt16( nCode );
542 n -= std::min<sal_uInt16>(n, 2);
543
544 if ( nCode == 0x0fd2 )
545 {
546 sal_uInt16 nPatternId;
547 r.ReadUInt16( nPatternId );
548
549 sal_uInt8 Hor_Align, Ver_Align, temp;
550 bool bIsBold,bIsUnderLine,bIsItalics;
551
552 r.SeekRel(12);
553
554 // Read 17th Byte
555 r.ReadUChar( temp );
556
557 bIsBold = (temp & 0x01);
558 bIsItalics = (temp & 0x02);
559 bIsUnderLine = (temp & 0x04);
560
561 if ( bIsBold )
563 if ( bIsItalics )
565 if ( bIsUnderLine )
567
568 r.SeekRel(3);
569
570 // Read 21st Byte
571 r.ReadUChar( Hor_Align );
572 OP_HorAlign123(rContext, Hor_Align, rItemSet );
573
574 r.ReadUChar( Ver_Align );
575 OP_VerAlign123(rContext, Ver_Align, rItemSet );
576
577 rContext.aLotusPatternPool.emplace( nPatternId, aPattern );
578 n -= std::min<sal_uInt16>(n, 20);
579 }
580 r.SeekRel(n);
581}
582
583void OP_SheetName123(LotusContext& rContext, SvStream& rStream, sal_uInt16 nLength)
584{
585 if (nLength <= 4)
586 {
587 rStream.SeekRel(nLength);
588 return;
589 }
590
591 // B0 36 [sheet number (2 bytes?)] [sheet name (null terminated char array)]
592 rStream.SeekRel(2); // ignore the first 2 bytes (B0 36).
593 sal_uInt16 nSheetNum(0);
594 rStream.ReadUInt16(nSheetNum);
595
596 const size_t nStrLen = nLength - 4;
597 std::vector<char> sSheetName(nStrLen + 1);
598 sSheetName[rStream.ReadBytes(sSheetName.data(), nStrLen)] = 0;
599
600 if (!ValidTab(nSheetNum))
601 return;
602 // coverity[tainted_data : FALSE] - ValidTab has sanitized nSheetNum
603 rContext.rDoc.MakeTable(nSheetNum);
604 if (!sSheetName.empty())
605 {
606 OUString aName(sSheetName.data(), strlen(sSheetName.data()), rContext.eCharset);
607 rContext.rDoc.RenameTab(nSheetNum, aName);
608 }
609}
610
612{
613 sal_uInt16 nOpcode, nLength;
614 sal_uInt16 nCol = 0, nColCount = 0, nRow = 0, nRowCount = 0, nTab = 0, nData, nTabCount = 0, nLevel = 0;
615
616 do
617 {
618 rStream.ReadUInt16( nOpcode ).ReadUInt16( nLength );
619 switch ( nOpcode )
620 {
622 nLevel++;
623 break;
625 nLevel--;
626 if( nLevel == 1 )
627 {
628 nTab = nTab + nTabCount;
629 nCol = 0; nColCount = 0;
630 nRow = 0; nRowCount = 0;
631 }
632 break;
634 if( nLength >= 2 )
635 {
636 rStream.ReadUInt16( nData );
637 rStream.SeekRel( nLength - 2 );
638 if( nLevel == 1 )
639 nTabCount = SanitizeTab(nData);
640 else if( nLevel == 2 )
641 {
642 nCol = nCol + nColCount;
643 nColCount = nData;
644 if ( nCol > 0xff ) // 256 is the max col size supported by 123
645 nCol = 0;
646 }
647 else if( nLevel == 3 )
648 {
649 nRow = nRow + nRowCount;
650 nRowCount = nData;
651 if ( nRow > 0x1fff ) // 8192 is the max row size supported by 123
652 nRow = 0;
653 }
654 }
655 else
656 rStream.SeekRel( nLength );
657 break;
659 if( nLength >= 2 )
660 {
661 rStream.ReadUInt16( nData );
662 rStream.SeekRel( nLength - 2 );
663 std::map<sal_uInt16, ScPatternAttr>::iterator loc = rContext.aLotusPatternPool.find( nData );
664 // #126338# apparently, files with invalid index occur in the wild -> don't crash then
665 if ( loc != rContext.aLotusPatternPool.end() )
666 for( int i = 0; i < nTabCount; i++)
667 {
668 rContext.rDoc.ApplyPatternAreaTab( nCol, nRow, nCol + nColCount - 1, nRow + nRowCount - 1, static_cast< SCTAB >( nTab + i ), loc->second );
669 }
670 }
671 else
672 rStream.SeekRel( nLength );
673 break;
674 default:
675 rStream.SeekRel( nLength );
676 break;
677 }
678 }
679 while( nLevel && rStream.good() );
680
681 rContext.aLotusPatternPool.clear();
682}
683
684/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool ValidTab(SCTAB nTab)
Definition: address.hxx:111
SCTAB SanitizeTab(SCTAB nTab)
Definition: address.hxx:145
bool good() const
Definition: formel.hxx:126
void Append(const ScDocument *pDoc, std::unique_ptr< LotusRange > pLR)
Definition: tool.cxx:401
virtual void Convert(std::unique_ptr< ScTokenArray > &rpErg, sal_Int32 &nRest) override
Definition: lotform.cxx:391
void Reset(const ScAddress &rEingPos)
Definition: lotform.cxx:363
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 SCCOL MaxCol() const
Definition: document.hxx:892
SC_DLLPUBLIC bool RenameTab(SCTAB nTab, const OUString &rName, bool bExternalDocument=false)
Definition: document.cxx:837
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6050
SC_DLLPUBLIC void EnsureTable(SCTAB nTab)
Definition: documen2.cxx:577
SC_DLLPUBLIC void ApplyPatternAreaTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScPatternAttr &rAttr)
Definition: document.cxx:4770
bool ValidAddress(const ScAddress &rAddress) const
Definition: document.hxx:904
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
SCCOL SanitizeCol(SCCOL nCol) const
Definition: document.hxx:905
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:899
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:601
SCTAB GetMaxTableNumber() const
Definition: document.hxx:817
SC_DLLPUBLIC void SetColWidth(SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth)
Definition: document.cxx:4086
bool ValidColRow(SCCOL nCol, SCROW nRow) const
Definition: document.hxx:901
void AddRecalcMode(ScRecalcMode)
static ScPostIt * CreateNoteFromString(ScDocument &rDoc, const ScAddress &rPos, const OUString &rNoteText, bool bShown, bool bAlwaysCreateCaption, sal_uInt32 nPostItId=0)
Creates a cell note based on the passed string and inserts it into the document.
Definition: postit.cxx:965
SfxItemSet & GetItemSet()
Definition: patattr.hxx:192
static OUString ConvertToScDefinedName(const OUString &rName)
Converts a string to a valid Calc defined name or database range name.
Definition: ftools.cxx:149
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
bool good() const
SvStream & ReadDouble(double &rDouble)
SvStream & ReadInt16(sal_Int16 &rInt16)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
std::size_t ReadBytes(void *pData, std::size_t nSize)
sal_uInt64 SeekRel(sal_Int64 nPos)
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
SvStream & ReadUChar(unsigned char &rChar)
static bool IsFuzzing()
int nCount
sal_Int16 nValue
LINESTYLE_SINGLE
ITALIC_NORMAL
WEIGHT_BOLD
constexpr auto TWIPS_PER_CHAR
Definition: global.hxx:85
OUString aName
sal_Int64 n
sal_Int16 nBit
int i
void OP_Number(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:88
void OP_Label123(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:362
void OP_BOF123(LotusContext &, SvStream &r, sal_uInt16)
Definition: op.cxx:352
void OP_CreatePattern123(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:534
void OP_Label(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:109
static sal_uInt16 nDefWidth
Definition: op.cxx:50
void OP_Margins(LotusContext &, SvStream &r, sal_uInt16 n)
Definition: op.cxx:287
void OP_ColumnWidth(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:170
void OP_Header(LotusContext &, SvStream &r, sal_uInt16 n)
Definition: op.cxx:282
void OP_HorAlign123(LotusContext &, sal_uInt8 nAlignPattern, SfxItemSet &rPatternItemSet)
Definition: op.cxx:472
void NI(LotusContext &, SvStream &r, sal_uInt16 n)
Definition: op.cxx:52
void OP_SymphNamedRange(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:236
void OP_BOF(LotusContext &, SvStream &r, sal_uInt16)
Definition: op.cxx:57
void OP_IEEENumber123(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:431
void OP_Note123(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:450
void OP_Formula123(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:400
void OP_Window1(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:313
void OP_SheetName123(LotusContext &rContext, SvStream &rStream, sal_uInt16 nLength)
Definition: op.cxx:583
void OP_VerAlign123(LotusContext &, sal_uInt8 nAlignPattern, SfxItemSet &rPatternItemSet)
Definition: op.cxx:505
void OP_EOF123(LotusContext &rContext, SvStream &, sal_uInt16)
Definition: op.cxx:357
void OP_Number123(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:380
void OP_Integer(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:67
void OP_Footer(LotusContext &, SvStream &r, sal_uInt16 n)
Definition: op.cxx:277
void OP_EOF(LotusContext &rContext, SvStream &, sal_uInt16)
Definition: op.cxx:62
void OP_Formula(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:134
void OP_HiddenCols(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:292
void OP_Blank(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:341
void OP_ApplyPatternArea123(LotusContext &rContext, SvStream &rStream)
Definition: op.cxx:611
void OP_NamedRange(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:195
#define LOTUS_FORMAT_INFO
Definition: optab.h:42
#define ROW_FORMAT_MARKER
Definition: optab.h:44
#define COL_FORMAT_MARKER
Definition: optab.h:46
#define LOTUS_FORMAT_INDEX
Definition: optab.h:40
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
constexpr TypedWhichId< SvxPostureItem > ATTR_FONT_POSTURE(103)
constexpr TypedWhichId< SvxWeightItem > ATTR_FONT_WEIGHT(102)
constexpr TypedWhichId< SvxHorJustifyItem > ATTR_HOR_JUSTIFY(129)
constexpr TypedWhichId< SvxVerJustifyItem > ATTR_VER_JUSTIFY(132)
constexpr TypedWhichId< SvxUnderlineItem > ATTR_FONT_UNDERLINE(104)
std::map< sal_uInt16, ScPatternAttr > aLotusPatternPool
Definition: lotfilter.hxx:45
ScDocument & rDoc
Definition: lotfilter.hxx:44
LotusRangeList maRangeNames
Definition: lotfilter.hxx:51
rtl_TextEncoding eCharset
Definition: lotfilter.hxx:43
void PutFormString(LotusContext &rContext, SCCOL nCol, SCROW nRow, SCTAB nTab, char *pString)
Definition: tool.cxx:38
const sal_uInt8 nFractionalFloat
Definition: tool.h:31
const sal_uInt8 nFractionalStd
Definition: tool.h:30
void SetFormat(LotusContext &rContext, SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt8 nFormat, sal_uInt8 nSt)
Definition: tool.cxx:88
double Snum32ToDouble(sal_uInt32 nValue)
Definition: tool.cxx:129
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
sal_Int32 nLength