Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/doc/DocumentLinksAdministrationManager.cxx
Warning:line 81, column 25
Use of memory after it is freed

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 DocumentLinksAdministrationManager.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/core/doc/DocumentLinksAdministrationManager.cxx

/home/maarten/src/libreoffice/core/sw/source/core/doc/DocumentLinksAdministrationManager.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 <DocumentLinksAdministrationManager.hxx>
21
22#include <doc.hxx>
23#include <DocumentSettingManager.hxx>
24#include <IDocumentUndoRedo.hxx>
25#include <IDocumentState.hxx>
26#include <IDocumentMarkAccess.hxx>
27#include <sfx2/objsh.hxx>
28#include <sfx2/linkmgr.hxx>
29#include <sfx2/docfile.hxx>
30#include <dialoghelp.hxx>
31#include <linkenum.hxx>
32#include <com/sun/star/document/UpdateDocMode.hpp>
33#include <swtypes.hxx>
34#include <docsh.hxx>
35#include <bookmrk.hxx>
36#include <swserv.hxx>
37#include <swbaslnk.hxx>
38#include <section.hxx>
39#include <docary.hxx>
40#include <frmfmt.hxx>
41#include <fmtcntnt.hxx>
42#include <swtable.hxx>
43#include <ndtxt.hxx>
44#include <frameformats.hxx>
45#include <tools/urlobj.hxx>
46#include <unotools/charclass.hxx>
47#include <unotools/securityoptions.hxx>
48
49using namespace ::com::sun::star;
50
51//Helper functions for this file
52namespace
53{
54 struct FindItem
55 {
56 const OUString m_Item;
57 SwTableNode* pTableNd;
58 SwSectionNode* pSectNd;
59
60 explicit FindItem(const OUString& rS)
61 : m_Item(rS), pTableNd(nullptr), pSectNd(nullptr)
62 {}
63 };
64
65 ::sfx2::SvBaseLink* lcl_FindNextRemovableLink( const ::sfx2::SvBaseLinks& rLinks )
66 {
67 for (const auto& rLinkIter : rLinks)
68 {
69 ::sfx2::SvBaseLink& rLnk = *rLinkIter;
70 if ((sfx2::SvBaseLinkObjectType::ClientGraphic == rLnk.GetObjType() || sfx2::SvBaseLinkObjectType::ClientFile == rLnk.GetObjType())
4
Assuming the condition is true
5
Taking true branch
71 && dynamic_cast<const SwBaseLink*>(&rLnk) != nullptr)
72 {
73 tools::SvRef<sfx2::SvBaseLink> xLink(&rLnk);
74
75 OUString sFName;
76 sfx2::LinkManager::GetDisplayNames( xLink.get(), nullptr, &sFName );
77
78 INetURLObject aURL( sFName );
79 if( INetProtocol::File == aURL.GetProtocol() ||
6
Assuming the condition is true
80 INetProtocol::Cid == aURL.GetProtocol() )
81 return &rLnk;
7
Calling '~SvRef'
15
Returning from '~SvRef'
16
Use of memory after it is freed
82 }
83 }
84 return nullptr;
85 }
86
87
88 ::sw::mark::DdeBookmark* lcl_FindDdeBookmark( const IDocumentMarkAccess& rMarkAccess, const OUString& rName, const bool bCaseSensitive )
89 {
90 //Iterating over all bookmarks, checking DdeBookmarks
91 const OUString sNameLc = bCaseSensitive ? rName : GetAppCharClass().lowercase(rName);
92 for(IDocumentMarkAccess::const_iterator_t ppMark = rMarkAccess.getAllMarksBegin();
93 ppMark != rMarkAccess.getAllMarksEnd();
94 ++ppMark)
95 {
96 if (::sw::mark::DdeBookmark* const pBkmk = dynamic_cast< ::sw::mark::DdeBookmark*>(*ppMark))
97 {
98 if (
99 (bCaseSensitive && (pBkmk->GetName() == sNameLc)) ||
100 (!bCaseSensitive && GetAppCharClass().lowercase(pBkmk->GetName()) == sNameLc)
101 )
102 {
103 return pBkmk;
104 }
105 }
106 }
107 return nullptr;
108 }
109
110
111 bool lcl_FindSection( const SwSectionFormat* pSectFormat, FindItem * const pItem, bool bCaseSensitive )
112 {
113 SwSection* pSect = pSectFormat->GetSection();
114 if( pSect )
115 {
116 OUString sNm( bCaseSensitive
117 ? pSect->GetSectionName()
118 : GetAppCharClass().lowercase( pSect->GetSectionName() ));
119 OUString sCompare( bCaseSensitive
120 ? pItem->m_Item
121 : GetAppCharClass().lowercase( pItem->m_Item ) );
122 if( sNm == sCompare )
123 {
124 // found, so get the data
125 const SwNodeIndex* pIdx = pSectFormat->GetContent().GetContentIdx();
126 if( pIdx && &pSectFormat->GetDoc()->GetNodes() == &pIdx->GetNodes() )
127 {
128 // a table in the normal NodesArr
129 pItem->pSectNd = pIdx->GetNode().GetSectionNode();
130 return false;
131 }
132 // If the name is already correct, but not the rest then we don't have them.
133 // The names are always unique.
134 }
135 }
136 return true;
137 }
138
139 bool lcl_FindTable( const SwFrameFormat* pTableFormat, FindItem * const pItem )
140 {
141 OUString sNm( GetAppCharClass().lowercase( pTableFormat->GetName() ));
142 if ( sNm == pItem->m_Item )
143 {
144 SwTable* pTmpTable = SwTable::FindTable( pTableFormat );
145 if( pTmpTable )
146 {
147 SwTableBox* pFBox = pTmpTable->GetTabSortBoxes()[0];
148 if( pFBox && pFBox->GetSttNd() &&
149 &pTableFormat->GetDoc()->GetNodes() == &pFBox->GetSttNd()->GetNodes() )
150 {
151 // a table in the normal NodesArr
152 pItem->pTableNd = const_cast<SwTableNode*>(
153 pFBox->GetSttNd()->FindTableNode());
154 return false;
155 }
156 }
157 // If the name is already correct, but not the rest then we don't have them.
158 // The names are always unique.
159 }
160 return true;
161 }
162
163}
164
165
166namespace sw
167{
168
169DocumentLinksAdministrationManager::DocumentLinksAdministrationManager( SwDoc& i_rSwdoc )
170 : mbVisibleLinks(true)
171 , mbLinksUpdated( false ) //#i38810#
172 , m_pLinkMgr( new sfx2::LinkManager(nullptr) )
173 , m_rDoc( i_rSwdoc )
174{
175}
176
177bool DocumentLinksAdministrationManager::IsVisibleLinks() const
178{
179 return mbVisibleLinks;
180}
181
182void DocumentLinksAdministrationManager::SetVisibleLinks(bool bFlag)
183{
184 mbVisibleLinks = bFlag;
185}
186
187sfx2::LinkManager& DocumentLinksAdministrationManager::GetLinkManager()
188{
189 return *m_pLinkMgr;
190}
191
192const sfx2::LinkManager& DocumentLinksAdministrationManager::GetLinkManager() const
193{
194 return *m_pLinkMgr;
195}
196
197// #i42634# Moved common code of SwReader::Read() and SwDocShell::UpdateLinks()
198// to new SwDoc::UpdateLinks():
199void DocumentLinksAdministrationManager::UpdateLinks()
200{
201 if (!m_rDoc.GetDocShell())
202 return;
203 SfxObjectCreateMode eMode = m_rDoc.GetDocShell()->GetCreateMode();
204 if (eMode == SfxObjectCreateMode::INTERNAL)
205 return;
206 if (eMode == SfxObjectCreateMode::ORGANIZER)
207 return;
208 if (m_rDoc.GetDocShell()->IsPreview())
209 return;
210 if (GetLinkManager().GetLinks().empty())
211 return;
212 sal_uInt16 nLinkMode = m_rDoc.GetDocumentSettingManager().getLinkUpdateMode(true);
213 sal_uInt16 nUpdateDocMode = m_rDoc.GetDocShell()->GetUpdateDocMode();
214 if (nLinkMode == NEVER && nUpdateDocMode != document::UpdateDocMode::FULL_UPDATE)
215 return;
216
217 bool bAskUpdate = nLinkMode == MANUAL;
218 bool bUpdate = true;
219 switch(nUpdateDocMode)
220 {
221 case document::UpdateDocMode::NO_UPDATE: bUpdate = false;break;
222 case document::UpdateDocMode::QUIET_UPDATE:bAskUpdate = false; break;
223 case document::UpdateDocMode::FULL_UPDATE: bAskUpdate = true; break;
224 }
225 if (nLinkMode == AUTOMATIC && !bAskUpdate)
226 {
227 SfxMedium * medium = m_rDoc.GetDocShell()->GetMedium();
228 if (!SvtSecurityOptions().isTrustedLocationUriForUpdatingLinks(
229 medium == nullptr ? OUString() : medium->GetName()))
230 {
231 bAskUpdate = true;
232 }
233 }
234 comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = m_rDoc.GetDocShell()->getEmbeddedObjectContainer();
235 if (bUpdate)
236 {
237 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);
238
239 weld::Window* pDlgParent = GetFrameWeld(m_rDoc.GetDocShell());
240 GetLinkManager().UpdateAllLinks(bAskUpdate, false, pDlgParent);
241 }
242 else
243 {
244 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false);
245 }
246}
247
248bool DocumentLinksAdministrationManager::GetData( const OUString& rItem, const OUString& rMimeType,
249 uno::Any & rValue ) const
250{
251 // search for bookmarks and sections case sensitive at first. If nothing is found then try again case insensitive
252 bool bCaseSensitive = true;
253 while( true )
254 {
255 ::sw::mark::DdeBookmark* const pBkmk = lcl_FindDdeBookmark(*m_rDoc.getIDocumentMarkAccess(), rItem, bCaseSensitive);
256 if(pBkmk)
257 return SwServerObject(*pBkmk).GetData(rValue, rMimeType);
258
259 // Do we already have the Item?
260 OUString sItem( bCaseSensitive ? rItem : GetAppCharClass().lowercase(rItem));
261 FindItem aPara( sItem );
262 for( const SwSectionFormat* pFormat : m_rDoc.GetSections() )
263 {
264 if (!(lcl_FindSection(pFormat, &aPara, bCaseSensitive)))
265 break;
266 }
267 if( aPara.pSectNd )
268 {
269 // found, so get the data
270 return SwServerObject( *aPara.pSectNd ).GetData( rValue, rMimeType );
271 }
272 if( !bCaseSensitive )
273 break;
274 bCaseSensitive = false;
275 }
276
277 FindItem aPara( GetAppCharClass().lowercase( rItem ));
278 for( const SwFrameFormat* pFormat : *m_rDoc.GetTableFrameFormats() )
279 {
280 if (!(lcl_FindTable(pFormat, &aPara)))
281 break;
282 }
283 if( aPara.pTableNd )
284 {
285 return SwServerObject( *aPara.pTableNd ).GetData( rValue, rMimeType );
286 }
287
288 return false;
289}
290
291void DocumentLinksAdministrationManager::SetData( const OUString& rItem )
292{
293 // search for bookmarks and sections case sensitive at first. If nothing is found then try again case insensitive
294 bool bCaseSensitive = true;
295 while( true )
296 {
297 ::sw::mark::DdeBookmark* const pBkmk = lcl_FindDdeBookmark(*m_rDoc.getIDocumentMarkAccess(), rItem, bCaseSensitive);
298 if(pBkmk)
299 {
300 return;
301 }
302
303 // Do we already have the Item?
304 OUString sItem( bCaseSensitive ? rItem : GetAppCharClass().lowercase(rItem));
305 FindItem aPara( sItem );
306 for( const SwSectionFormat* pFormat : m_rDoc.GetSections() )
307 {
308 if (!(lcl_FindSection(pFormat, &aPara, bCaseSensitive)))
309 break;
310 }
311 if( aPara.pSectNd )
312 {
313 // found, so get the data
314 return;
315 }
316 if( !bCaseSensitive )
317 break;
318 bCaseSensitive = false;
319 }
320
321 OUString sItem(GetAppCharClass().lowercase(rItem));
322 FindItem aPara( sItem );
323 for( const SwFrameFormat* pFormat : *m_rDoc.GetTableFrameFormats() )
324 {
325 if (!(lcl_FindTable(pFormat, &aPara)))
326 break;
327 }
328}
329
330::sfx2::SvLinkSource* DocumentLinksAdministrationManager::CreateLinkSource(const OUString& rItem)
331{
332 SwServerObject* pObj = nullptr;
333
334 // search for bookmarks and sections case sensitive at first. If nothing is found then try again case insensitive
335 bool bCaseSensitive = true;
336 while( true )
337 {
338 // bookmarks
339 ::sw::mark::DdeBookmark* const pBkmk = lcl_FindDdeBookmark(*m_rDoc.getIDocumentMarkAccess(), rItem, bCaseSensitive);
340 if(pBkmk && pBkmk->IsExpanded())
341 {
342 pObj = pBkmk->GetRefObject();
343 if( !pObj )
344 {
345 // mark found, but no link yet -> create hotlink
346 pObj = new SwServerObject(*pBkmk);
347 pBkmk->SetRefObject(pObj);
348 GetLinkManager().InsertServer(pObj);
349 }
350 }
351 if(pObj)
352 return pObj;
353
354 FindItem aPara(bCaseSensitive ? rItem : GetAppCharClass().lowercase(rItem));
355 // sections
356 for( const SwSectionFormat* pFormat : m_rDoc.GetSections() )
357 {
358 if (!(lcl_FindSection(pFormat, &aPara, bCaseSensitive)))
359 break;
360 }
361
362 if(aPara.pSectNd)
363 {
364 pObj = aPara.pSectNd->GetSection().GetObject();
365 if( !pObj )
366 {
367 // section found, but no link yet -> create hotlink
368 pObj = new SwServerObject( *aPara.pSectNd );
369 aPara.pSectNd->GetSection().SetRefObject( pObj );
370 GetLinkManager().InsertServer(pObj);
371 }
372 }
373 if(pObj)
374 return pObj;
375 if( !bCaseSensitive )
376 break;
377 bCaseSensitive = false;
378 }
379
380 FindItem aPara( GetAppCharClass().lowercase(rItem) );
381 // tables
382 for( const SwFrameFormat* pFormat : *m_rDoc.GetTableFrameFormats() )
383 {
384 if (!(lcl_FindTable(pFormat, &aPara)))
385 break;
386 }
387 if(aPara.pTableNd)
388 {
389 pObj = aPara.pTableNd->GetTable().GetObject();
390 if( !pObj )
391 {
392 // table found, but no link yet -> create hotlink
393 pObj = new SwServerObject(*aPara.pTableNd);
394 aPara.pTableNd->GetTable().SetRefObject(pObj);
395 GetLinkManager().InsertServer(pObj);
396 }
397 }
398 return pObj;
399}
400
401/// embedded all local links (Areas/Graphics)
402bool DocumentLinksAdministrationManager::EmbedAllLinks()
403{
404 bool bRet = false;
405 sfx2::LinkManager& rLnkMgr = GetLinkManager();
406 const ::sfx2::SvBaseLinks& rLinks = rLnkMgr.GetLinks();
407 if( !rLinks.empty() )
1
Assuming the condition is true
2
Taking true branch
408 {
409 ::sw::UndoGuard const undoGuard(m_rDoc.GetIDocumentUndoRedo());
410
411 ::sfx2::SvBaseLink* pLnk = nullptr;
412 while( nullptr != (pLnk = lcl_FindNextRemovableLink( rLinks ) ) )
3
Calling 'lcl_FindNextRemovableLink'
413 {
414 tools::SvRef<sfx2::SvBaseLink> xLink = pLnk;
415 // Tell the link that it's being destroyed!
416 xLink->Closed();
417
418 // if one forgot to remove itself
419 if( xLink.is() )
420 rLnkMgr.Remove( xLink.get() );
421
422 bRet = true;
423 }
424
425 m_rDoc.GetIDocumentUndoRedo().DelAllUndoObj();
426 m_rDoc.getIDocumentState().SetModified();
427 }
428 return bRet;
429}
430
431void DocumentLinksAdministrationManager::SetLinksUpdated(const bool bNewLinksUpdated)
432{
433 mbLinksUpdated = bNewLinksUpdated;
434}
435
436bool DocumentLinksAdministrationManager::LinksUpdated() const
437{
438 return mbLinksUpdated;
439}
440
441DocumentLinksAdministrationManager::~DocumentLinksAdministrationManager()
442{
443}
444
445bool DocumentLinksAdministrationManager::SelectServerObj( const OUString& rStr, SwPaM*& rpPam, std::unique_ptr<SwNodeRange>& rpRange ) const
446{
447 // Do we actually have the Item?
448 rpPam = nullptr;
449 rpRange = nullptr;
450
451 OUString sItem( INetURLObject::decode( rStr,
452 INetURLObject::DecodeMechanism::WithCharset ));
453
454 sal_Int32 nPos = sItem.indexOf( cMarkSeparator );
455
456 const CharClass& rCC = GetAppCharClass();
457
458 // Extension for sections: not only link bookmarks/sections
459 // but also frames (text!), tables, outlines:
460 if( -1 != nPos )
461 {
462 bool bContinue = false;
463 OUString sName( sItem.copy( 0, nPos ) );
464 OUString sCmp( sItem.copy( nPos + 1 ));
465 sItem = rCC.lowercase( sItem );
466
467 FindItem aPara( sName );
468
469 if( sCmp == "table" )
470 {
471 sName = rCC.lowercase( sName );
472 for( const SwFrameFormat* pFormat : *m_rDoc.GetTableFrameFormats() )
473 {
474 if (!(lcl_FindTable(pFormat, &aPara)))
475 break;
476 }
477 if( aPara.pTableNd )
478 {
479 rpRange.reset(new SwNodeRange( *aPara.pTableNd, 0,
480 *aPara.pTableNd->EndOfSectionNode(), 1 ));
481 return true;
482 }
483 }
484 else if( sCmp == "frame" )
485 {
486 const SwFlyFrameFormat* pFlyFormat = m_rDoc.FindFlyByName( sName );
487 if( pFlyFormat )
488 {
489 SwNodeIndex* pIdx = const_cast<SwNodeIndex*>(pFlyFormat->GetContent().GetContentIdx());
490 if( pIdx )
491 {
492 SwNode* pNd = &pIdx->GetNode();
493 if( !pNd->IsNoTextNode() )
494 {
495 rpRange.reset(new SwNodeRange( *pNd, 1, *pNd->EndOfSectionNode() ));
496 return true;
497 }
498 }
499 }
500 }
501 else if( sCmp == "region" )
502 {
503 sItem = sName; // Is being dealt with further down!
504 bContinue = true;
505 }
506 else if( sCmp == "outline" )
507 {
508 SwPosition aPos( SwNodeIndex( m_rDoc.GetNodes() ));
509 if (m_rDoc.GotoOutline(aPos, sName, nullptr))
510 {
511 SwNode* pNd = &aPos.nNode.GetNode();
512 const int nLvl = pNd->GetTextNode()->GetAttrOutlineLevel()-1;
513
514 const SwOutlineNodes& rOutlNds = m_rDoc.GetNodes().GetOutLineNds();
515 SwOutlineNodes::size_type nTmpPos;
516 (void)rOutlNds.Seek_Entry( pNd, &nTmpPos );
517 rpRange.reset(new SwNodeRange( aPos.nNode, 0, aPos.nNode ));
518
519 // look for the section's end, now
520 for( ++nTmpPos;
521 nTmpPos < rOutlNds.size() &&
522 nLvl < rOutlNds[ nTmpPos ]->GetTextNode()->
523 GetAttrOutlineLevel()-1;
524 ++nTmpPos )
525 ; // there is no block
526
527 if( nTmpPos < rOutlNds.size() )
528 rpRange->aEnd = *rOutlNds[ nTmpPos ];
529 else
530 rpRange->aEnd = m_rDoc.GetNodes().GetEndOfContent();
531 return true;
532 }
533 }
534
535 if( !bContinue )
536 return false;
537 }
538
539 // search for bookmarks and sections case sensitive at first. If nothing is found then try again case insensitive
540 bool bCaseSensitive = true;
541 while( true )
542 {
543 ::sw::mark::DdeBookmark* const pBkmk = lcl_FindDdeBookmark(*m_rDoc.getIDocumentMarkAccess(), sItem, bCaseSensitive);
544 if(pBkmk)
545 {
546 if(pBkmk->IsExpanded())
547 rpPam = new SwPaM(
548 pBkmk->GetMarkPos(),
549 pBkmk->GetOtherMarkPos());
550 return static_cast<bool>(rpPam);
551 }
552
553 FindItem aPara( bCaseSensitive ? sItem : rCC.lowercase( sItem ) );
554
555 if( !m_rDoc.GetSections().empty() )
556 {
557 for( const SwSectionFormat* pFormat : m_rDoc.GetSections() )
558 {
559 if (!(lcl_FindSection(pFormat, &aPara, bCaseSensitive)))
560 break;
561 }
562 if( aPara.pSectNd )
563 {
564 rpRange.reset(new SwNodeRange( *aPara.pSectNd, 1,
565 *aPara.pSectNd->EndOfSectionNode() ));
566 return true;
567
568 }
569 }
570 if( !bCaseSensitive )
571 break;
572 bCaseSensitive = false;
573 }
574 return false;
575}
576
577
578}
579
580
581/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/tools/ref.hxx

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#ifndef INCLUDED_TOOLS_REF_HXX
20#define INCLUDED_TOOLS_REF_HXX
21
22#include <sal/config.h>
23#include <cassert>
24#include <tools/toolsdllapi.h>
25#include <utility>
26
27/**
28 This implements similar functionality to boost::intrusive_ptr
29*/
30
31namespace tools {
32
33/** T must be a class that extends SvRefBase */
34template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final {
35public:
36 SvRef(): pObj(nullptr) {}
37
38 SvRef(SvRef&& rObj) noexcept
39 {
40 pObj = rObj.pObj;
41 rObj.pObj = nullptr;
42 }
43
44 SvRef(SvRef const & rObj): pObj(rObj.pObj)
45 {
46 if (pObj != nullptr) pObj->AddNextRef();
47 }
48
49 SvRef(T * pObjP): pObj(pObjP)
50 {
51 if (pObj != nullptr) pObj->AddFirstRef();
52 }
53
54 ~SvRef()
55 {
56 if (pObj != nullptr) pObj->ReleaseRef();
8
Taking true branch
9
Calling 'SvRefBase::ReleaseRef'
14
Returning; memory was released
57 }
58
59 void clear()
60 {
61 if (pObj != nullptr) {
62 T * pRefObj = pObj;
63 pObj = nullptr;
64 pRefObj->ReleaseRef();
65 }
66 }
67
68 SvRef & operator =(SvRef const & rObj)
69 {
70 if (rObj.pObj != nullptr) {
71 rObj.pObj->AddNextRef();
72 }
73 T * pRefObj = pObj;
74 pObj = rObj.pObj;
75 if (pRefObj != nullptr) {
76 pRefObj->ReleaseRef();
77 }
78 return *this;
79 }
80
81 SvRef & operator =(SvRef && rObj)
82 {
83 if (pObj != nullptr) {
84 pObj->ReleaseRef();
85 }
86 pObj = rObj.pObj;
87 rObj.pObj = nullptr;
88 return *this;
89 }
90
91 bool is() const { return pObj != nullptr; }
92
93 explicit operator bool() const { return is(); }
94
95 T * get() const { return pObj; }
96
97 T * operator ->() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail
("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 97, __extension__ __PRETTY_FUNCTION__))
; return pObj; }
98
99 T & operator *() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail
("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 99, __extension__ __PRETTY_FUNCTION__))
; return *pObj; }
100
101 bool operator ==(const SvRef<T> &rhs) const { return pObj == rhs.pObj; }
102 bool operator !=(const SvRef<T> &rhs) const { return !(*this == rhs); }
103
104private:
105 T * pObj;
106};
107
108/**
109 * This implements similar functionality to std::make_shared.
110 */
111template<typename T, typename... Args>
112SvRef<T> make_ref(Args&& ... args)
113{
114 return SvRef<T>(new T(std::forward<Args>(args)...));
115}
116
117}
118
119/** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */
120class TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) SvRefBase
121{
122 // work around a clang 3.5 optimization bug: if the bNoDelete is *first*
123 // it mis-compiles "if (--nRefCount == 0)" and never deletes any object
124 unsigned int nRefCount : 31;
125 // the only reason this is not bool is because MSVC cannot handle mixed type bitfields
126 unsigned int bNoDelete : 1;
127
128protected:
129 virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE;
130
131public:
132 SvRefBase() : nRefCount(0), bNoDelete(1) {}
133 SvRefBase(const SvRefBase &) : nRefCount(0), bNoDelete(1) {}
134
135 SvRefBase & operator=(const SvRefBase &) { return *this; }
136
137 void RestoreNoDelete()
138 { bNoDelete = 1; }
139
140 void AddNextRef()
141 {
142 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) &&
"Do not add refs to dead objects") ? void (0) : __assert_fail
("nRefCount < (1 << 30) && \"Do not add refs to dead objects\""
, "/home/maarten/src/libreoffice/core/include/tools/ref.hxx",
142, __extension__ __PRETTY_FUNCTION__))
;
143 ++nRefCount;
144 }
145
146 void AddFirstRef()
147 {
148 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) &&
"Do not add refs to dead objects") ? void (0) : __assert_fail
("nRefCount < (1 << 30) && \"Do not add refs to dead objects\""
, "/home/maarten/src/libreoffice/core/include/tools/ref.hxx",
148, __extension__ __PRETTY_FUNCTION__))
;
149 if( bNoDelete )
150 bNoDelete = 0;
151 ++nRefCount;
152 }
153
154 void ReleaseRef()
155 {
156 assert( nRefCount >= 1)(static_cast <bool> (nRefCount >= 1) ? void (0) : __assert_fail
("nRefCount >= 1", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 156, __extension__ __PRETTY_FUNCTION__))
;
10
'?' condition is true
157 if( --nRefCount == 0 && !bNoDelete
11.1
Field 'bNoDelete' is 0
11.1
Field 'bNoDelete' is 0
)
11
Assuming the condition is true
12
Taking true branch
158 {
159 // I'm not sure about the original purpose of this line, but right now
160 // it serves the purpose that anything that attempts to do an AddRef()
161 // after an object is deleted will trip an assert.
162 nRefCount = 1 << 30;
163 delete this;
13
Memory is released
164 }
165 }
166
167 unsigned int GetRefCount() const
168 { return nRefCount; }
169};
170
171template<typename T>
172class SvCompatWeakBase;
173
174/** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T.
175*/
176template<typename T>
177class SvCompatWeakHdl final : public SvRefBase
178{
179 friend class SvCompatWeakBase<T>;
180 T* _pObj;
181
182 SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {}
183
184public:
185 void ResetWeakBase( ) { _pObj = nullptr; }
186 T* GetObj() { return _pObj; }
187};
188
189/** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame.
190 Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted.
191*/
192template<typename T>
193class SvCompatWeakBase
194{
195 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
196
197public:
198 /** Does not use initializer due to compiler warnings,
199 because the lifetime of the _xHdl object can exceed the lifetime of this class.
200 */
201 SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); }
202
203 ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); }
204
205 SvCompatWeakHdl<T>* GetHdl() { return _xHdl.get(); }
206};
207
208/** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak.
209*/
210template<typename T>
211class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef
212{
213 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
214public:
215 SvCompatWeakRef( ) {}
216 SvCompatWeakRef( T* pObj )
217 { if( pObj ) _xHdl = pObj->GetHdl(); }
218#if defined(__COVERITY__)
219 ~SvCompatWeakRef() COVERITY_NOEXCEPT_FALSE {}
220#endif
221 SvCompatWeakRef& operator = ( T * pObj )
222 { _xHdl = pObj ? pObj->GetHdl() : nullptr; return *this; }
223 bool is() const
224 { return _xHdl.is() && _xHdl->GetObj(); }
225 explicit operator bool() const { return is(); }
226 T* operator -> () const
227 { return _xHdl.is() ? _xHdl->GetObj() : nullptr; }
228 operator T* () const
229 { return _xHdl.is() ? _xHdl->GetObj() : nullptr; }
230};
231
232#endif
233
234/* vim:set shiftwidth=4 softtabstop=4 expandtab: */