7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-19 00:21:36 +00:00

Guard against null m_part in erc TextVar checks

Also removes duplication of LIB_SYMBOL dummy() construction methods

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19575
This commit is contained in:
JamesJCode 2025-01-10 00:12:54 +00:00
parent 229507ee43
commit 35172fe402
6 changed files with 88 additions and 115 deletions

View File

@ -276,56 +276,59 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
testAssertion( &field, sheet, screen, field.GetText(), field.GetPosition() );
}
symbol->GetLibSymbolRef()->RunOnChildren(
[&]( SCH_ITEM* child )
{
if( child->Type() == SCH_FIELD_T )
if( symbol->GetLibSymbolRef() )
{
symbol->GetLibSymbolRef()->RunOnChildren(
[&]( SCH_ITEM* child )
{
// test only SCH_SYMBOL fields, not LIB_SYMBOL fields
}
else if( child->Type() == SCH_TEXT_T )
{
SCH_TEXT* textItem = static_cast<SCH_TEXT*>( child );
if( unresolved( textItem->GetShownText( &sheet, true ) ) )
if( child->Type() == SCH_FIELD_T )
{
auto ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
ercItem->SetItems( symbol );
ercItem->SetSheetSpecificPath( sheet );
BOX2I bbox = textItem->GetBoundingBox();
bbox = symbol->GetTransform().TransformCoordinate( bbox );
VECTOR2I pos = bbox.Centre() + symbol->GetPosition();
SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
screen->Append( marker );
// test only SCH_SYMBOL fields, not LIB_SYMBOL fields
}
testAssertion( symbol, sheet, screen, textItem->GetText(),
textItem->GetPosition() );
}
else if( child->Type() == SCH_TEXTBOX_T )
{
SCH_TEXTBOX* textboxItem = static_cast<SCH_TEXTBOX*>( child );
if( unresolved( textboxItem->GetShownText( &sheet, true ) ) )
else if( child->Type() == SCH_TEXT_T )
{
auto ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
ercItem->SetItems( symbol );
ercItem->SetSheetSpecificPath( sheet );
SCH_TEXT* textItem = static_cast<SCH_TEXT*>( child );
BOX2I bbox = textboxItem->GetBoundingBox();
bbox = symbol->GetTransform().TransformCoordinate( bbox );
VECTOR2I pos = bbox.Centre() + symbol->GetPosition();
if( unresolved( textItem->GetShownText( &sheet, true ) ) )
{
auto ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
ercItem->SetItems( symbol );
ercItem->SetSheetSpecificPath( sheet );
SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
screen->Append( marker );
BOX2I bbox = textItem->GetBoundingBox();
bbox = symbol->GetTransform().TransformCoordinate( bbox );
VECTOR2I pos = bbox.Centre() + symbol->GetPosition();
SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
screen->Append( marker );
}
testAssertion( symbol, sheet, screen, textItem->GetText(),
textItem->GetPosition() );
}
else if( child->Type() == SCH_TEXTBOX_T )
{
SCH_TEXTBOX* textboxItem = static_cast<SCH_TEXTBOX*>( child );
testAssertion( symbol, sheet, screen, textboxItem->GetText(),
textboxItem->GetPosition() );
}
} );
if( unresolved( textboxItem->GetShownText( &sheet, true ) ) )
{
auto ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
ercItem->SetItems( symbol );
ercItem->SetSheetSpecificPath( sheet );
BOX2I bbox = textboxItem->GetBoundingBox();
bbox = symbol->GetTransform().TransformCoordinate( bbox );
VECTOR2I pos = bbox.Centre() + symbol->GetPosition();
SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
screen->Append( marker );
}
testAssertion( symbol, sheet, screen, textboxItem->GetText(),
textboxItem->GetPosition() );
}
} );
}
}
else if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( item ) )
{

View File

@ -219,6 +219,35 @@ const LIB_SYMBOL& LIB_SYMBOL::operator=( const LIB_SYMBOL& aSymbol )
}
/**
* Used as a dummy LIB_SYMBOL when one is not found in library or imported schematic
*
* This symbol is a 400 mils square with the text "??"
*/
LIB_SYMBOL* LIB_SYMBOL::GetDummy()
{
static LIB_SYMBOL* symbol;
if( !symbol )
{
symbol = new LIB_SYMBOL( wxEmptyString );
SCH_SHAPE* square = new SCH_SHAPE( SHAPE_T::RECTANGLE, LAYER_DEVICE );
square->SetPosition( VECTOR2I( schIUScale.MilsToIU( -200 ), schIUScale.MilsToIU( 200 ) ) );
square->SetEnd( VECTOR2I( schIUScale.MilsToIU( 200 ), schIUScale.MilsToIU( -200 ) ) );
symbol->AddDrawItem( square );
SCH_TEXT* text = new SCH_TEXT( { 0, 0 }, wxT( "??" ), LAYER_DEVICE );
text->SetTextSize( VECTOR2I( schIUScale.MilsToIU( 150 ), schIUScale.MilsToIU( 150 ) ) );
symbol->AddDrawItem( text );
}
return symbol;
}
unsigned LIB_SYMBOL::GetInheritanceDepth() const
{
unsigned depth = 0;

View File

@ -102,6 +102,11 @@ public:
return dupe;
}
/**
* Returns a dummy LIB_SYMBOL, used when one is missing in the schematic
*/
static LIB_SYMBOL* GetDummy();
void SetParent( LIB_SYMBOL* aParent = nullptr );
LIB_SYMBOL_REF& GetParent() { return m_parent; }
const LIB_SYMBOL_REF& GetParent() const { return m_parent; }

View File

@ -97,43 +97,6 @@ std::vector<KICAD_T> SCH_PAINTER::g_ScaledSelectionTypes = {
};
/**
* Used when a LIB_SYMBOL is not found in library to draw a dummy shape.
* This symbol is a 400 mils square with the text "??"
*
* DEF DUMMY U 0 40 Y Y 1 0 N
* F0 "U" 0 -350 60 H V
* F1 "DUMMY" 0 350 60 H V
* DRAW
* T 0 0 0 150 0 0 0 ??
* S -200 200 200 -200 0 1 0
* ENDDRAW
* ENDDEF
*/
static LIB_SYMBOL* dummy()
{
static LIB_SYMBOL* symbol;
if( !symbol )
{
symbol = new LIB_SYMBOL( wxEmptyString );
SCH_SHAPE* square = new SCH_SHAPE( SHAPE_T::RECTANGLE, LAYER_DEVICE );
square->SetPosition( VECTOR2I( schIUScale.MilsToIU( -200 ), schIUScale.MilsToIU( 200 ) ) );
square->SetEnd( VECTOR2I( schIUScale.MilsToIU( 200 ), schIUScale.MilsToIU( -200 ) ) );
symbol->AddDrawItem( square );
SCH_TEXT* text = new SCH_TEXT( { 0, 0 }, wxT( "??" ), LAYER_DEVICE );
text->SetTextSize( VECTOR2I( schIUScale.MilsToIU( 150 ), schIUScale.MilsToIU( 150 ) ) );
symbol->AddDrawItem( text );
}
return symbol;
}
SCH_PAINTER::SCH_PAINTER( GAL* aGal ) :
KIGFX::PAINTER( aGal ),
m_schematic( nullptr )
@ -2217,8 +2180,8 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
int bodyStyle = aSymbol->GetBodyStyle();
// Use dummy symbol if the actual couldn't be found (or couldn't be locked).
LIB_SYMBOL* originalSymbol = aSymbol->GetLibSymbolRef() ? aSymbol->GetLibSymbolRef().get()
: dummy();
LIB_SYMBOL* originalSymbol =
aSymbol->GetLibSymbolRef() ? aSymbol->GetLibSymbolRef().get() : LIB_SYMBOL::GetDummy();
std::vector<SCH_PIN*> originalPins = originalSymbol->GetPins( unit, bodyStyle );
// Copy the source so we can re-orient and translate it.

View File

@ -67,35 +67,6 @@ std::string toUTFTildaText( const wxString& txt )
}
/**
* Used to draw a dummy shape when a LIB_SYMBOL is not found in library
*
* This symbol is a 400 mils square with the text "??"
*/
static LIB_SYMBOL* dummy()
{
static LIB_SYMBOL* symbol;
if( !symbol )
{
symbol = new LIB_SYMBOL( wxEmptyString );
SCH_SHAPE* square = new SCH_SHAPE( SHAPE_T::RECTANGLE, LAYER_DEVICE );
square->SetPosition( VECTOR2I( schIUScale.MilsToIU( -200 ), schIUScale.MilsToIU( 200 ) ) );
square->SetEnd( VECTOR2I( schIUScale.MilsToIU( 200 ), schIUScale.MilsToIU( -200 ) ) );
symbol->AddDrawItem( square );
SCH_TEXT* text = new SCH_TEXT( { 0, 0 }, wxT( "??"), LAYER_DEVICE );
text->SetTextSize( VECTOR2I( schIUScale.MilsToIU( 150 ), schIUScale.MilsToIU( 150 ) ) );
symbol->AddDrawItem( text );
}
return symbol;
}
SCH_SYMBOL::SCH_SYMBOL() :
SYMBOL( nullptr, SCH_SYMBOL_T )
{
@ -543,9 +514,10 @@ void SCH_SYMBOL::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBo
tempSymbol.Print( &localRenderSettings, m_unit, m_bodyStyle, m_pos + aOffset, false,
aDimmed );
}
else // Use dummy() part if the actual cannot be found.
else // Use a dummy part if the actual cannot be found.
{
dummy()->Print( &localRenderSettings, 0, 0, m_pos + aOffset, aForceNoFill, aDimmed );
LIB_SYMBOL::GetDummy()->Print( &localRenderSettings, 0, 0, m_pos + aOffset, aForceNoFill,
aDimmed );
}
for( SCH_FIELD& field : m_fields )
@ -1999,7 +1971,8 @@ BOX2I SCH_SYMBOL::doGetBoundingBox( bool aIncludePins, bool aIncludeFields ) con
if( m_part )
bBox = m_part->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins, false );
else
bBox = dummy()->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins, false );
bBox = LIB_SYMBOL::GetDummy()->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins,
false );
bBox = m_transform.TransformCoordinate( bBox );
bBox.Normalize();
@ -2079,7 +2052,7 @@ void SCH_SYMBOL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_
// part and alias can differ if alias is not the root
if( m_part )
{
if( m_part.get() != dummy() )
if( m_part.get() != LIB_SYMBOL::GetDummy() )
{
if( m_part->IsPower() )
{

View File

@ -127,7 +127,7 @@ public:
* be edited so a check for this symbol must be performed before attempting to edit the
* library symbol with the library editor or it will crash KiCad.
*
* @see dummy()
* @see LIB_SYMBOL::GetDummy()
*
* @return true if the library symbol is missing or false if it is valid.
*/