Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/filter/ascii/ascatr.cxx
Warning:line 335, column 25
Value stored to 'nStrPos' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ascatr.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/filter/ascii/ascatr.cxx
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 <hintids.hxx>
21#include <tools/stream.hxx>
22#include <comphelper/string.hxx>
23#include <pam.hxx>
24#include <doc.hxx>
25#include <ndtxt.hxx>
26#include <IDocumentRedlineAccess.hxx>
27#include <redline.hxx>
28#include "wrtasc.hxx"
29#include <txatbase.hxx>
30#include <txtfld.hxx>
31#include <fmtftn.hxx>
32#include <fmtfld.hxx>
33#include <fldbas.hxx>
34#include <ftninfo.hxx>
35#include <numrule.hxx>
36
37#include <algorithm>
38
39/*
40 * This file contains all output functions of the ASCII-Writer;
41 * For all nodes, attributes, formats and chars.
42 */
43
44namespace {
45
46class SwASC_AttrIter
47{
48 SwASCWriter& rWrt;
49 const SwTextNode& rNd;
50 sal_Int32 nCurrentSwPos;
51
52 sal_Int32 SearchNext( sal_Int32 nStartPos );
53
54public:
55 SwASC_AttrIter( SwASCWriter& rWrt, const SwTextNode& rNd, sal_Int32 nStt );
56
57 void NextPos()
58 {
59 nCurrentSwPos = SearchNext( nCurrentSwPos + 1 );
60 }
61
62 sal_Int32 WhereNext() const
63 {
64 return nCurrentSwPos;
65 }
66
67 bool OutAttr( sal_Int32 nSwPos );
68};
69
70}
71
72SwASC_AttrIter::SwASC_AttrIter(
73 SwASCWriter& rWr,
74 const SwTextNode& rTextNd,
75 sal_Int32 nStt )
76 : rWrt( rWr )
77 , rNd( rTextNd )
78 , nCurrentSwPos( 0 )
79{
80 nCurrentSwPos = SearchNext( nStt + 1 );
81}
82
83sal_Int32 SwASC_AttrIter::SearchNext( sal_Int32 nStartPos )
84{
85 sal_Int32 nMinPos = SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF);
86 const SwpHints* pTextAttrs = rNd.GetpSwpHints();
87 if( pTextAttrs )
88 {
89 // TODO: This can be optimized, if we make use of the fact that the TextAttrs
90 // are sorted by starting position. We would need to remember two indices, however.
91 for ( size_t i = 0; i < pTextAttrs->Count(); ++i )
92 {
93 const SwTextAttr* pHt = pTextAttrs->Get(i);
94 if ( pHt->HasDummyChar() )
95 {
96 sal_Int32 nPos = pHt->GetStart();
97
98 if( nPos >= nStartPos && nPos <= nMinPos )
99 nMinPos = nPos;
100
101 if( ( ++nPos ) >= nStartPos && nPos < nMinPos )
102 nMinPos = nPos;
103 }
104 else if ( pHt->HasContent() )
105 {
106 const sal_Int32 nHintStart = pHt->GetStart();
107 if ( nHintStart >= nStartPos && nHintStart <= nMinPos )
108 {
109 nMinPos = nHintStart;
110 }
111
112 const sal_Int32 nHintEnd = pHt->End() ? *pHt->End() : COMPLETE_STRING;
113 if ( nHintEnd >= nStartPos && nHintEnd < nMinPos )
114 {
115 nMinPos = nHintEnd;
116 }
117 }
118 }
119 }
120 return nMinPos;
121}
122
123bool SwASC_AttrIter::OutAttr( sal_Int32 nSwPos )
124{
125 bool bRet = false;
126 const SwpHints* pTextAttrs = rNd.GetpSwpHints();
127 if( pTextAttrs )
128 {
129 for( size_t i = 0; i < pTextAttrs->Count(); ++i )
130 {
131 const SwTextAttr* pHt = pTextAttrs->Get(i);
132 if ( ( pHt->HasDummyChar()
133 || pHt->HasContent() )
134 && nSwPos == pHt->GetStart() )
135 {
136 bRet = true;
137 OUString sOut;
138 switch( pHt->Which() )
139 {
140 case RES_TXTATR_FIELD:
141 case RES_TXTATR_ANNOTATION:
142 case RES_TXTATR_INPUTFIELD:
143 sOut = static_txtattr_cast<SwTextField const*>(pHt)
144 ->GetFormatField().GetField()->ExpandField(true, nullptr);
145 break;
146
147 case RES_TXTATR_FTN:
148 {
149 const SwFormatFootnote& rFootnote = pHt->GetFootnote();
150 if( !rFootnote.GetNumStr().isEmpty() )
151 sOut = rFootnote.GetNumStr();
152 else if( rFootnote.IsEndNote() )
153 sOut = rWrt.m_pDoc->GetEndNoteInfo().m_aFormat.
154 GetNumStr( rFootnote.GetNumber() );
155 else
156 sOut = rWrt.m_pDoc->GetFootnoteInfo().m_aFormat.
157 GetNumStr( rFootnote.GetNumber() );
158 }
159 break;
160 }
161 if( !sOut.isEmpty() )
162 rWrt.Strm().WriteUnicodeOrByteText( sOut );
163 }
164 else if( nSwPos < pHt->GetStart() )
165 break;
166 }
167 }
168 return bRet;
169}
170
171namespace {
172
173class SwASC_RedlineIter
174{
175private:
176 SwTextNode const& m_rNode;
177 IDocumentRedlineAccess const& m_rIDRA;
178 SwRedlineTable::size_type m_nextRedline;
179
180public:
181 SwASC_RedlineIter(SwASCWriter const& rWriter, SwTextNode const& rNode)
182 : m_rNode(rNode)
183 , m_rIDRA(rNode.GetDoc().getIDocumentRedlineAccess())
184 , m_nextRedline(rWriter.m_bHideDeleteRedlines
185 ? m_rIDRA.GetRedlinePos(m_rNode, RedlineType::Delete)
186 : SwRedlineTable::npos)
187 {
188 }
189
190 bool CheckNodeDeleted()
191 {
192 if (m_nextRedline == SwRedlineTable::npos)
193 {
194 return false;
195 }
196 SwRangeRedline const*const pRedline(m_rIDRA.GetRedlineTable()[m_nextRedline]);
197 return pRedline->Start()->nNode.GetIndex() < m_rNode.GetIndex()
198 && m_rNode.GetIndex() < pRedline->End()->nNode.GetIndex();
199 }
200
201 std::pair<sal_Int32, sal_Int32> GetNextRedlineSkip()
202 {
203 sal_Int32 nRedlineStart(COMPLETE_STRING);
204 sal_Int32 nRedlineEnd(COMPLETE_STRING);
205 for ( ; m_nextRedline < m_rIDRA.GetRedlineTable().size(); ++m_nextRedline)
206 {
207 SwRangeRedline const*const pRedline(m_rIDRA.GetRedlineTable()[m_nextRedline]);
208 if (pRedline->GetType() != RedlineType::Delete)
209 {
210 continue;
211 }
212 SwPosition const*const pStart(pRedline->Start());
213 SwPosition const*const pEnd(pRedline->End());
214 if (m_rNode.GetIndex() < pStart->nNode.GetIndex())
215 {
216 m_nextRedline = SwRedlineTable::npos;
217 break; // done
218 }
219 if (nRedlineStart == COMPLETE_STRING)
220 {
221 nRedlineStart = pStart->nNode.GetIndex() == m_rNode.GetIndex()
222 ? pStart->nContent.GetIndex()
223 : 0;
224 }
225 else
226 {
227 if (pStart->nContent.GetIndex() != nRedlineEnd)
228 {
229 assert(nRedlineEnd < pStart->nContent.GetIndex())(static_cast <bool> (nRedlineEnd < pStart->nContent
.GetIndex()) ? void (0) : __assert_fail ("nRedlineEnd < pStart->nContent.GetIndex()"
, "/home/maarten/src/libreoffice/core/sw/source/filter/ascii/ascatr.cxx"
, 229, __extension__ __PRETTY_FUNCTION__))
;
230 break; // no increment, revisit it next call
231 }
232 }
233 nRedlineEnd = pEnd->nNode.GetIndex() == m_rNode.GetIndex()
234 ? pEnd->nContent.GetIndex()
235 : COMPLETE_STRING;
236 }
237 return std::make_pair(nRedlineStart, nRedlineEnd);
238 }
239};
240
241}
242
243// Output of the node
244
245static Writer& OutASC_SwTextNode( Writer& rWrt, SwContentNode& rNode )
246{
247 const SwTextNode& rNd = static_cast<SwTextNode&>(rNode);
248
249 sal_Int32 nStrPos = rWrt.m_pCurrentPam->GetPoint()->nContent.GetIndex();
250 const sal_Int32 nNodeEnd = rNd.Len();
251 sal_Int32 nEnd = nNodeEnd;
252 bool bLastNd = rWrt.m_pCurrentPam->GetPoint()->nNode == rWrt.m_pCurrentPam->GetMark()->nNode;
253 if( bLastNd )
254 nEnd = rWrt.m_pCurrentPam->GetMark()->nContent.GetIndex();
255
256 bool bIsOneParagraph = rWrt.m_pOrigPam->Start()->nNode == rWrt.m_pOrigPam->End()->nNode;
257
258 SwASC_AttrIter aAttrIter( static_cast<SwASCWriter&>(rWrt), rNd, nStrPos );
259 SwASC_RedlineIter redlineIter(static_cast<SwASCWriter&>(rWrt), rNd);
260
261 if (redlineIter.CheckNodeDeleted())
262 {
263 return rWrt;
264 }
265
266 const SwNumRule* pNumRule = rNd.GetNumRule();
267 if (pNumRule && !nStrPos && rWrt.m_bExportParagraphNumbering && !bIsOneParagraph)
268 {
269 bool bIsOutlineNumRule = pNumRule == rNd.GetDoc().GetOutlineNumRule();
270
271 // indent each numbering level by 4 spaces
272 OUString level;
273 if (!bIsOutlineNumRule)
274 {
275 for (int i = 0; i <= rNd.GetActualListLevel(); ++i)
276 level += " ";
277 }
278
279 // set up bullets or numbering
280 OUString numString(rNd.GetNumString());
281 if (numString.isEmpty() && !bIsOutlineNumRule)
282 {
283 if (rNd.HasBullet() && !rNd.HasVisibleNumberingOrBullet())
284 numString = " ";
285 else if (rNd.HasBullet())
286 numString = OUString(numfunc::GetBulletChar(rNd.GetActualListLevel()));
287 else if (!rNd.HasBullet() && !rNd.HasVisibleNumberingOrBullet())
288 numString = " ";
289 }
290
291 if (!level.isEmpty() || !numString.isEmpty())
292 rWrt.Strm().WriteUnicodeOrByteText(level + numString + " ");
293 }
294
295 OUString aStr( rNd.GetText() );
296 if( rWrt.m_bASCII_ParaAsBlank )
297 aStr = aStr.replace(0x0A, ' ');
298
299 const bool bExportSoftHyphens = RTL_TEXTENCODING_UCS2(((rtl_TextEncoding) 0xFFFF)) == rWrt.GetAsciiOptions().GetCharSet() ||
300 RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)) == rWrt.GetAsciiOptions().GetCharSet();
301
302 std::pair<sal_Int32, sal_Int32> curRedline(redlineIter.GetNextRedlineSkip());
303 for (;;) {
304 const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
305
306 bool isOutAttr(false);
307 if (nStrPos < curRedline.first || curRedline.second <= nStrPos)
308 {
309 isOutAttr = aAttrIter.OutAttr(nStrPos);
310 }
311
312 if (!isOutAttr)
313 {
314 OUStringBuffer buf;
315 while (true)
316 {
317 if (nNextAttr <= curRedline.first)
318 {
319 buf.append(aStr.copy(nStrPos, nNextAttr - nStrPos));
320 break;
321 }
322 else if (nStrPos < curRedline.second)
323 {
324 if (nStrPos < curRedline.first)
325 {
326 buf.append(aStr.copy(nStrPos, curRedline.first - nStrPos));
327 }
328 if (curRedline.second <= nNextAttr)
329 {
330 nStrPos = curRedline.second;
331 curRedline = redlineIter.GetNextRedlineSkip();
332 }
333 else
334 {
335 nStrPos = nNextAttr;
Value stored to 'nStrPos' is never read
336 break;
337 }
338 }
339 else
340 {
341 curRedline = redlineIter.GetNextRedlineSkip();
342 }
343 }
344 OUString aOutStr(buf.makeStringAndClear());
345 if ( !bExportSoftHyphens )
346 aOutStr = aOutStr.replaceAll(OUStringChar(CHAR_SOFTHYPHENu'\x00AD'), "");
347
348 // all INWORD/BREAKWORD should be already removed by OutAttr
349 // but the field-marks are not attributes so filter those
350 static sal_Unicode const forbidden [] = {
351 CH_TXT_ATR_INPUTFIELDSTARTu'\x0004',
352 CH_TXT_ATR_INPUTFIELDENDu'\x0005',
353 CH_TXT_ATR_FORMELEMENTu'\x0006',
354 CH_TXT_ATR_FIELDSTARTu'\x0007',
355 CH_TXT_ATR_FIELDSEPu'\x0003',
356 CH_TXT_ATR_FIELDENDu'\x0008',
357 0
358 };
359 aOutStr = comphelper::string::removeAny(aOutStr, forbidden);
360
361 rWrt.Strm().WriteUnicodeOrByteText( aOutStr );
362 }
363 nStrPos = nNextAttr;
364 if (nStrPos >= nEnd)
365 {
366 break;
367 }
368 aAttrIter.NextPos();
369 }
370
371 if( !bLastNd ||
372 ( ( !rWrt.m_bWriteClipboardDoc && !rWrt.m_bASCII_NoLastLineEnd )
373 && !nStrPos && nEnd == nNodeEnd ) )
374 rWrt.Strm().WriteUnicodeOrByteText( static_cast<SwASCWriter&>(rWrt).GetLineEnd());
375
376 return rWrt;
377}
378
379/*
380 * Create the table for the ASCII function pointers to the output
381 * function.
382 * There are local structures that only need to be known to the ASCII DLL.
383 */
384
385SwNodeFnTab aASCNodeFnTab = {
386/* RES_TXTNODE */ OutASC_SwTextNode,
387/* RES_GRFNODE */ nullptr,
388/* RES_OLENODE */ nullptr
389};
390
391/* vim:set shiftwidth=4 softtabstop=4 expandtab: */