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>
31 #include <editeng/justifyitem.hxx>
32 #include <unotools/configmgr.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 
50 static sal_uInt16 nDefWidth = sal_uInt16( TWIPS_PER_CHAR * 10 );
51 
52 void NI(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 n)
53 {
54  r.SeekRel( n );
55 }
56 
57 void OP_BOF(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 /*n*/)
58 {
59  r.SeekRel( 2 ); // skip version number
60 }
61 
62 void OP_EOF(LotusContext& rContext, SvStream& /*r*/, sal_uInt16 /*n*/)
63 {
64  rContext.bEOF = true;
65 }
66 
67 void 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 
88 void 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 
109 void 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 
134 void 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 
150  svl::SharedStringPool& rSPool = rContext.rDoc.GetSharedStringPool();
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 
170 void 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 
195 void 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 
231  aTmp = ScfTools::ConvertToScDefinedName( aTmp );
232 
233  rContext.maRangeNames.Append( &rContext.rDoc, std::move(pRange) );
234 }
235 
236 void 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 );
272  aTmp = ScfTools::ConvertToScDefinedName( aTmp );
273 
274  rContext.maRangeNames.Append( &rContext.rDoc, std::move(pRange) );
275 }
276 
277 void OP_Footer(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 n)
278 {
279  r.SeekRel( n );
280 }
281 
282 void OP_Header(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 n)
283 {
284  r.SeekRel( n );
285 }
286 
287 void OP_Margins(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 n)
288 {
289  r.SeekRel( n );
290 }
291 
292 void 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 
313 void 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 
322  r.ReadUInt16( nDefWidth );
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 
341 void 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 
352 void OP_BOF123(LotusContext& /*rContext*/, SvStream& r, sal_uInt16 /*n*/)
353 {
354  r.SeekRel( 26 );
355 }
356 
357 void OP_EOF123(LotusContext& rContext, SvStream& /*r*/, sal_uInt16 /*n*/)
358 {
359  rContext.bEOF = true;
360 }
361 
362 void 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 
380 void 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 
400 void 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 
414  svl::SharedStringPool& rSPool = rContext.rDoc.GetSharedStringPool();
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 
431 void 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 
450 void 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 
472 void 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 
505 void 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 
534 void 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 )
562  rItemSet.Put( SvxWeightItem(WEIGHT_BOLD,ATTR_FONT_WEIGHT) );
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 
583 void 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  ::std::vector<char> sSheetName;
597  sSheetName.reserve(nLength-4);
598  for (sal_uInt16 i = 4; i < nLength; ++i)
599  {
600  char c;
601  rStream.ReadChar( c );
602  sSheetName.push_back(c);
603  }
604 
605  if (!ValidTab(nSheetNum))
606  return;
607  // coverity[tainted_data : FALSE] - ValidTab has sanitized nSheetNum
608  rContext.rDoc.MakeTable(nSheetNum);
609  if (!sSheetName.empty())
610  {
611  OUString aName(sSheetName.data(), strlen(sSheetName.data()), rContext.eCharset);
612  rContext.rDoc.RenameTab(nSheetNum, aName);
613  }
614 }
615 
617 {
618  sal_uInt16 nOpcode, nLength;
619  sal_uInt16 nCol = 0, nColCount = 0, nRow = 0, nRowCount = 0, nTab = 0, nData, nTabCount = 0, nLevel = 0;
620 
621  do
622  {
623  rStream.ReadUInt16( nOpcode ).ReadUInt16( nLength );
624  switch ( nOpcode )
625  {
626  case ROW_FORMAT_MARKER:
627  nLevel++;
628  break;
629  case COL_FORMAT_MARKER:
630  nLevel--;
631  if( nLevel == 1 )
632  {
633  nTab = nTab + nTabCount;
634  nCol = 0; nColCount = 0;
635  nRow = 0; nRowCount = 0;
636  }
637  break;
638  case LOTUS_FORMAT_INDEX:
639  if( nLength >= 2 )
640  {
641  rStream.ReadUInt16( nData );
642  rStream.SeekRel( nLength - 2 );
643  if( nLevel == 1 )
644  nTabCount = SanitizeTab(nData);
645  else if( nLevel == 2 )
646  {
647  nCol = nCol + nColCount;
648  nColCount = nData;
649  if ( nCol > 0xff ) // 256 is the max col size supported by 123
650  nCol = 0;
651  }
652  else if( nLevel == 3 )
653  {
654  nRow = nRow + nRowCount;
655  nRowCount = nData;
656  if ( nRow > 0x1fff ) // 8192 is the max row size supported by 123
657  nRow = 0;
658  }
659  }
660  else
661  rStream.SeekRel( nLength );
662  break;
663  case LOTUS_FORMAT_INFO:
664  if( nLength >= 2 )
665  {
666  rStream.ReadUInt16( nData );
667  rStream.SeekRel( nLength - 2 );
668  std::map<sal_uInt16, ScPatternAttr>::iterator loc = rContext.aLotusPatternPool.find( nData );
669  // #126338# apparently, files with invalid index occur in the wild -> don't crash then
670  if ( loc != rContext.aLotusPatternPool.end() )
671  for( int i = 0; i < nTabCount; i++)
672  {
673  rContext.rDoc.ApplyPatternAreaTab( nCol, nRow, nCol + nColCount - 1, nRow + nRowCount - 1, static_cast< SCTAB >( nTab + i ), loc->second );
674  }
675  }
676  else
677  rStream.SeekRel( nLength );
678  break;
679  default:
680  rStream.SeekRel( nLength );
681  break;
682  }
683  }
684  while( nLevel && rStream.good() );
685 
686  rContext.aLotusPatternPool.clear();
687 }
688 
689 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
rtl_TextEncoding eCharset
Definition: lotfilter.hxx:43
void OP_SymphNamedRange(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:236
SvStream & ReadInt16(sal_Int16 &rInt16)
SCCOL SanitizeCol(SCCOL nCol) const
Definition: document.hxx:886
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:567
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
void OP_Note123(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:450
#define COL_FORMAT_MARKER
Definition: optab.h:46
#define ROW_FORMAT_MARKER
Definition: optab.h:44
void OP_Label123(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:362
static OUString ConvertToScDefinedName(const OUString &rName)
Converts a string to a valid Calc defined name or database range name.
Definition: ftools.cxx:148
SC_DLLPUBLIC void SetColHidden(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bHidden)
Definition: document.cxx:4486
void OP_CreatePattern123(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:534
void OP_Header(LotusContext &, SvStream &r, sal_uInt16 n)
Definition: op.cxx:282
void OP_ColumnWidth(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:170
SC_DLLPUBLIC void SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
Definition: document.cxx:3494
void PutFormString(LotusContext &rContext, SCCOL nCol, SCROW nRow, SCTAB nTab, char *pString)
Definition: tool.cxx:38
void OP_Footer(LotusContext &, SvStream &r, sal_uInt16 n)
Definition: op.cxx:277
void OP_VerAlign123(LotusContext &, sal_uInt8 nAlignPattern, SfxItemSet &rPatternItemSet)
Definition: op.cxx:505
void NI(LotusContext &, SvStream &r, sal_uInt16 n)
Definition: op.cxx:52
sal_uInt64 SeekRel(sal_Int64 nPos)
void OP_EOF123(LotusContext &rContext, SvStream &, sal_uInt16)
Definition: op.cxx:357
ScDocument & rDoc
Definition: lotfilter.hxx:44
void Reset(const ScAddress &rEingPos)
Definition: lotform.cxx:363
LotusRangeList maRangeNames
Definition: lotfilter.hxx:51
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6075
void OP_BOF123(LotusContext &, SvStream &r, sal_uInt16)
Definition: op.cxx:352
WEIGHT_BOLD
void OP_Blank(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:341
void Append(const ScDocument *pDoc, std::unique_ptr< LotusRange > pLR)
Definition: tool.cxx:401
SC_DLLPUBLIC bool RenameTab(SCTAB nTab, const OUString &rName, bool bExternalDocument=false)
Definition: document.cxx:853
void OP_Margins(LotusContext &, SvStream &r, sal_uInt16 n)
Definition: op.cxx:287
SC_DLLPUBLIC void SetColWidth(SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth)
Definition: document.cxx:4102
static bool IsFuzzing()
int nCount
#define LOTUS_FORMAT_INFO
Definition: optab.h:42
double Snum32ToDouble(sal_uInt32 nValue)
Definition: tool.cxx:129
SCTAB GetMaxTableNumber() const
Definition: document.hxx:810
sal_uInt16 nCode
static sal_uInt16 nDefWidth
Definition: op.cxx:50
void OP_HiddenCols(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:292
void SetFormat(LotusContext &rContext, SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt8 nFormat, sal_uInt8 nSt)
Definition: tool.cxx:88
void OP_ApplyPatternArea123(LotusContext &rContext, SvStream &rStream)
Definition: op.cxx:616
void OP_HorAlign123(LotusContext &, sal_uInt8 nAlignPattern, SfxItemSet &rPatternItemSet)
Definition: op.cxx:472
constexpr TypedWhichId< SvxUnderlineItem > ATTR_FONT_UNDERLINE(104)
#define LOTUS_FORMAT_INDEX
Definition: optab.h:40
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:877
constexpr TypedWhichId< SvxPostureItem > ATTR_FONT_POSTURE(103)
int i
const sal_uInt8 nFractionalFloat
Definition: tool.h:31
void OP_Label(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:109
constexpr auto TWIPS_PER_CHAR
Definition: global.hxx:84
sal_Int16 SCCOL
Definition: types.hxx:21
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:880
constexpr TypedWhichId< SvxVerJustifyItem > ATTR_VER_JUSTIFY(132)
LINESTYLE_SINGLE
SC_DLLPUBLIC void ApplyPatternAreaTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScPatternAttr &rAttr)
Definition: document.cxx:4805
SvStream & ReadUChar(unsigned char &rChar)
void OP_SheetName123(LotusContext &rContext, SvStream &rStream, sal_uInt16 nLength)
Definition: op.cxx:583
SvStream & ReadDouble(double &rDouble)
bool ValidAddress(const ScAddress &rAddress) const
Definition: document.hxx:885
void OP_Window1(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:313
SC_DLLPUBLIC void EnsureTable(SCTAB nTab)
Definition: documen2.cxx:541
void OP_Formula123(LotusContext &rContext, SvStream &r, sal_uInt16 n)
Definition: op.cxx:400
std::size_t ReadBytes(void *pData, std::size_t nSize)
virtual void Convert(std::unique_ptr< ScTokenArray > &rpErg, sal_Int32 &nRest) override
Definition: lotform.cxx:391
bool ValidColRow(SCCOL nCol, SCROW nRow) const
Definition: document.hxx:882
const sal_uInt8 nFractionalStd
Definition: tool.h:30
void OP_Number(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:88
SCTAB SanitizeTab(SCTAB nTab)
Definition: address.hxx:138
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void OP_Integer(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:67
sal_Int32 SCROW
Definition: types.hxx:17
void OP_Number123(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:380
SvStream & ReadChar(char &rChar)
SC_DLLPUBLIC ScFormulaCell * SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell)
Set formula cell, and transfer its ownership to the document.
Definition: documen2.cxx:1087
ITALIC_NORMAL
unsigned char sal_uInt8
OUString aName
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
constexpr TypedWhichId< SvxWeightItem > ATTR_FONT_WEIGHT(102)
constexpr TypedWhichId< SvxHorJustifyItem > ATTR_HOR_JUSTIFY(129)
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
bool good() const
Definition: formel.hxx:125
bool good() const
void OP_BOF(LotusContext &, SvStream &r, sal_uInt16)
Definition: op.cxx:57
void OP_NamedRange(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:195
void OP_IEEENumber123(LotusContext &rContext, SvStream &r, sal_uInt16)
Definition: op.cxx:431
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:1274
sal_Int32 nLength
SC_DLLPUBLIC void MakeTable(SCTAB nTab, bool _bNeedsNameCheck=true)
Definition: document.cxx:168
void AddRecalcMode(ScRecalcMode)
std::map< sal_uInt16, ScPatternAttr > aLotusPatternPool
Definition: lotfilter.hxx:45
bool ValidTab(SCTAB nTab)
Definition: address.hxx:104
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 nValue