KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_view_null_safety.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
31
33
35#include <view/view.h>
36#include <view/view_group.h>
37
38using namespace KIGFX;
39
40namespace
41{
42class HIDDEN_GAL : public GAL
43{
44public:
45 HIDDEN_GAL( GAL_DISPLAY_OPTIONS& aOptions ) :
46 GAL( aOptions )
47 {
48 }
49
50 bool IsVisible() const override { return false; }
51};
52
53
54class REORDER_TEST_ITEM : public VIEW_ITEM
55{
56public:
57 REORDER_TEST_ITEM( int aLayer ) :
58 m_layer( aLayer )
59 {
60 }
61
62 wxString GetClass() const override { return wxT( "REORDER_TEST_ITEM" ); }
63
64 const BOX2I ViewBBox() const override { return BOX2I( VECTOR2I( 0, 0 ), VECTOR2I( 100, 100 ) ); }
65
66 std::vector<int> ViewGetLayers() const override { return { m_layer }; }
67
68private:
69 int m_layer;
70};
71} // namespace
72
73
74BOOST_AUTO_TEST_SUITE( ViewNullSafety )
75
76
77BOOST_AUTO_TEST_CASE( HideAndSetVisibleTolerateNullItem )
78{
79 VIEW view;
80
81 // Before the fix each of these dereferenced the null item via viewPrivData() and aborted.
82 view.Hide( nullptr, true );
83 view.Hide( nullptr, false, true );
84 view.SetVisible( nullptr, true );
85 view.SetVisible( nullptr, false );
86
87 // Reaching this point without crashing is the assertion.
88 BOOST_TEST( true );
89}
90
91
92BOOST_AUTO_TEST_CASE( ViewGroupRejectsNullItem )
93{
94 // Issue #24778: a re-entrant ExitGroup() during SCH_SELECTION_TOOL::EnterGroup() left the
95 // group overlay with a null (stale) member. VIEW_GROUP stored it, then the next repaint
96 // dereferenced it in ViewBBox()/ViewDraw(). Add() must drop a null the same way the VIEW
97 // mutators do.
99
100 group.Add( nullptr );
101
102 BOOST_TEST( group.GetSize() == 0u );
103
104 // Without the guard this iterated m_groupItems[0] on a null item and crashed.
105 group.ViewBBox();
106}
107
108
109BOOST_AUTO_TEST_CASE( ReorderLayerDataNonPermutationKeepsLayerTrees )
110{
111 GAL_DISPLAY_OPTIONS options;
112 HIDDEN_GAL gal( options );
113 VIEW view;
114
115 view.SetGAL( &gal );
116 view.ReorderLayerData( { { 11, 10 }, { 12, 11 } } );
117
118 REORDER_TEST_ITEM item( 12 );
119 view.Add( &item );
120
121 std::vector<VIEW::LAYER_ITEM_PAIR> found;
122 view.Query( BOX2I( VECTOR2I( -1, -1 ), VECTOR2I( 200, 200 ) ), found );
123
124 bool itemFound = false;
125
126 for( const VIEW::LAYER_ITEM_PAIR& pair : found )
127 {
128 if( pair.first == &item )
129 itemFound = true;
130 }
131
132 BOOST_TEST( itemFound );
133
134 view.Remove( &item );
135}
136
137
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
Abstract interface for drawing on a 2D-surface.
Extend VIEW_ITEM by possibility of grouping items into a single object.
Definition view_group.h:39
An abstract base class for deriving all objects that can be added to a VIEW.
Definition view_item.h:82
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:63
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition view.cpp:297
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:412
void SetGAL(GAL *aGal)
Assign a rendering device for the VIEW.
Definition view.cpp:592
int Query(const BOX2I &aRect, std::vector< LAYER_ITEM_PAIR > &aResult) const
Find all visible items that touch or are within the rectangle aRect.
Definition view.cpp:501
std::pair< VIEW_ITEM *, int > LAYER_ITEM_PAIR
Definition view.h:67
void Hide(VIEW_ITEM *aItem, bool aHide=true, bool aHideOverlay=false)
Temporarily hide the item in the view (e.g.
Definition view.cpp:1837
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition view.cpp:1813
void ReorderLayerData(std::unordered_map< int, int > aReorderMap)
Remap the data between layer ids without invalidating that data.
Definition view.cpp:762
The Cairo implementation of the graphics abstraction layer.
Definition eda_group.h:30
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_TEST(netlist.find("R_G1 ARM_OUT1 DIE_B R='0.001 / ((SW_STATE)") !=std::string::npos)
BOOST_AUTO_TEST_CASE(HideAndSetVisibleTolerateNullItem)
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708