Fix a pair of dereference-freed-pointers in DRC.

Fixes https://gitlab.com/kicad/code/kicad/issues/10335
This commit is contained in:
Jeff Young 2022-01-10 21:05:14 +00:00
parent 4cdfd14f25
commit 21790fcab7
8 changed files with 58 additions and 58 deletions

View File

@ -496,7 +496,7 @@ void RC_TREE_MODEL::DeleteItems( bool aCurrentOnly, bool aIncludeExclusions, boo
m_view->Freeze();
}
for( int i = m_rcItemsProvider->GetCount() - 1; i >= 0; --i )
for( int i = m_rcItemsProvider->GetCount( m_severities ) - 1; i >= 0; --i )
{
std::shared_ptr<RC_ITEM> rcItem = m_rcItemsProvider->GetItem( i );
MARKER_BASE* marker = rcItem->GetParent();

View File

@ -657,6 +657,9 @@ void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
{
bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_IGNORE;
m_ignoredList->InsertItem( m_ignoredList->GetItemCount(),
wxT( "" ) + rcItem->GetErrorText() );
std::vector<PCB_MARKER*>& markers = m_frame->GetBoard()->Markers();
for( unsigned i = 0; i < markers.size(); )

View File

@ -441,7 +441,7 @@ void PANEL_SETUP_RULES::OnCompile( wxCommandEvent& event )
try
{
std::vector<DRC_RULE*> dummyRules;
std::vector<std::shared_ptr<DRC_RULE>> dummyRules;
DRC_RULES_PARSER parser( m_textEditor->GetText(), _( "DRC rules" ) );

View File

@ -85,8 +85,7 @@ DRC_ENGINE::DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS *aSettings ) :
DRC_ENGINE::~DRC_ENGINE()
{
for( DRC_RULE* rule : m_rules )
delete rule;
m_rules.clear();
for( std::pair<DRC_CONSTRAINT_T, std::vector<DRC_ENGINE_CONSTRAINT*>*> pair : m_constraintMap )
{
@ -127,9 +126,9 @@ static bool isKeepoutZone( const BOARD_ITEM* aItem, bool aCheckFlags )
}
DRC_RULE* DRC_ENGINE::createImplicitRule( const wxString& name )
std::shared_ptr<DRC_RULE> DRC_ENGINE::createImplicitRule( const wxString& name )
{
DRC_RULE *rule = new DRC_RULE;
std::shared_ptr<DRC_RULE> rule = std::make_shared<DRC_RULE>();
rule->m_Name = name;
rule->m_Implicit = true;
@ -148,7 +147,7 @@ void DRC_ENGINE::loadImplicitRules()
// 1) global defaults
DRC_RULE* rule = createImplicitRule( _( "board setup constraints" ) );
std::shared_ptr<DRC_RULE> rule = createImplicitRule( _( "board setup constraints" ) );
DRC_CONSTRAINT clearanceConstraint( CLEARANCE_CONSTRAINT );
clearanceConstraint.Value().SetMin( bds.m_MinClearance );
@ -216,7 +215,7 @@ void DRC_ENGINE::loadImplicitRules()
// 2) micro-via specific defaults (new DRC doesn't treat microvias in any special way)
DRC_RULE* uViaRule = createImplicitRule( _( "board setup micro-via constraints" ) );
std::shared_ptr<DRC_RULE> uViaRule = createImplicitRule( _( "board setup micro-via constraints" ) );
uViaRule->m_Condition = new DRC_RULE_CONDITION( "A.Via_Type == 'Micro'" );
@ -237,7 +236,7 @@ void DRC_ENGINE::loadImplicitRules()
if( !bds.m_BlindBuriedViaAllowed )
{
DRC_RULE* bbViaRule = createImplicitRule( _( "board setup constraints" ) );
std::shared_ptr<DRC_RULE> bbViaRule = createImplicitRule( _( "board setup constraints" ) );
bbViaRule->m_Condition = new DRC_RULE_CONDITION( "A.Via_Type == 'Blind/buried'" );
@ -248,20 +247,18 @@ void DRC_ENGINE::loadImplicitRules()
// 3) per-netclass rules
std::vector<DRC_RULE*> netclassClearanceRules;
std::vector<DRC_RULE*> netclassItemSpecificRules;
std::vector<std::shared_ptr<DRC_RULE>> netclassClearanceRules;
std::vector<std::shared_ptr<DRC_RULE>> netclassItemSpecificRules;
auto makeNetclassRules =
[&]( const NETCLASSPTR& nc, bool isDefault )
{
wxString ncName = nc->GetName();
DRC_RULE* netclassRule;
wxString expr;
wxString expr;
if( nc->GetClearance() || nc->GetTrackWidth() )
{
netclassRule = new DRC_RULE;
std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
netclassRule->m_Name = wxString::Format( _( "netclass '%s'" ), ncName );
netclassRule->m_Implicit = true;
@ -288,7 +285,7 @@ void DRC_ENGINE::loadImplicitRules()
if( nc->GetDiffPairWidth() )
{
netclassRule = new DRC_RULE;
std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
netclassRule->m_Name = wxString::Format( _( "netclass '%s' (diff pair)" ),
ncName );
netclassRule->m_Implicit = true;
@ -305,7 +302,7 @@ void DRC_ENGINE::loadImplicitRules()
if( nc->GetDiffPairGap() )
{
netclassRule = new DRC_RULE;
std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
netclassRule->m_Name = wxString::Format( _( "netclass '%s' (diff pair)" ),
ncName );
netclassRule->m_Implicit = true;
@ -323,7 +320,7 @@ void DRC_ENGINE::loadImplicitRules()
// trimmed to the board min clearance, which is absolute).
if( nc->GetDiffPairGap() < nc->GetClearance() )
{
netclassRule = new DRC_RULE;
netclassRule = std::make_shared<DRC_RULE>();
netclassRule->m_Name = wxString::Format( _( "netclass '%s' (diff pair)" ),
ncName );
netclassRule->m_Implicit = true;
@ -342,7 +339,7 @@ void DRC_ENGINE::loadImplicitRules()
if( nc->GetViaDiameter() || nc->GetViaDrill() )
{
netclassRule = new DRC_RULE;
std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
netclassRule->m_Name = wxString::Format( _( "netclass '%s'" ), ncName );
netclassRule->m_Implicit = true;
@ -370,7 +367,7 @@ void DRC_ENGINE::loadImplicitRules()
if( nc->GetuViaDiameter() || nc->GetuViaDrill() )
{
netclassRule = new DRC_RULE;
std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
netclassRule->m_Name = wxString::Format( _( "netclass '%s'" ), ncName );
netclassRule->m_Implicit = true;
@ -409,16 +406,16 @@ void DRC_ENGINE::loadImplicitRules()
// The item-specific netclass rules are all unary, so there's no 'A' vs 'B' issue.
std::sort( netclassClearanceRules.begin(), netclassClearanceRules.end(),
[]( DRC_RULE* lhs, DRC_RULE* rhs )
[]( const std::shared_ptr<DRC_RULE>& lhs, const std::shared_ptr<DRC_RULE>& rhs )
{
return lhs->m_Constraints[0].m_Value.Min()
< rhs->m_Constraints[0].m_Value.Min();
} );
for( DRC_RULE* ncRule : netclassClearanceRules )
for( std::shared_ptr<DRC_RULE>& ncRule : netclassClearanceRules )
addRule( ncRule );
for( DRC_RULE* ncRule : netclassItemSpecificRules )
for( std::shared_ptr<DRC_RULE>& ncRule : netclassItemSpecificRules )
addRule( ncRule );
// 3) keepout area rules
@ -485,7 +482,7 @@ void DRC_ENGINE::loadRules( const wxFileName& aPath )
{
if( aPath.FileExists() )
{
std::vector<DRC_RULE*> rules;
std::vector<std::shared_ptr<DRC_RULE>> rules;
FILE* fp = wxFopen( aPath.GetFullPath(), wxT( "rt" ) );
@ -498,7 +495,7 @@ void DRC_ENGINE::loadRules( const wxFileName& aPath )
// Copy the rules into the member variable afterwards so that if Parse() throws then
// the possibly malformed rules won't contaminate the current ruleset.
for( DRC_RULE* rule : rules )
for( std::shared_ptr<DRC_RULE>& rule : rules )
m_rules.push_back( rule );
}
}
@ -508,7 +505,7 @@ void DRC_ENGINE::compileRules()
{
ReportAux( wxString::Format( "Compiling Rules (%d rules): ", (int) m_rules.size() ) );
for( DRC_RULE* rule : m_rules )
for( std::shared_ptr<DRC_RULE>& rule : m_rules )
{
DRC_RULE_CONDITION* condition = nullptr;
@ -545,9 +542,6 @@ void DRC_ENGINE::InitEngine( const wxFileName& aRulePath )
provider->SetDRCEngine( this );
}
for( DRC_RULE* rule : m_rules )
delete rule;
m_rules.clear();
m_rulesValid = false;

View File

@ -194,7 +194,7 @@ public:
static std::shared_ptr<SHAPE> GetShape( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer );
private:
void addRule( DRC_RULE* rule )
void addRule( std::shared_ptr<DRC_RULE>& rule )
{
m_rules.push_back(rule);
}
@ -210,36 +210,36 @@ private:
struct DRC_ENGINE_CONSTRAINT
{
LSET layerTest;
DRC_RULE_CONDITION* condition;
DRC_RULE* parentRule;
DRC_CONSTRAINT constraint;
LSET layerTest;
DRC_RULE_CONDITION* condition;
std::shared_ptr<DRC_RULE> parentRule;
DRC_CONSTRAINT constraint;
};
void loadImplicitRules();
DRC_RULE* createImplicitRule( const wxString& name );
std::shared_ptr<DRC_RULE> createImplicitRule( const wxString& name );
protected:
BOARD_DESIGN_SETTINGS* m_designSettings;
BOARD* m_board;
DS_PROXY_VIEW_ITEM* m_drawingSheet;
NETLIST* m_schematicNetlist;
BOARD_DESIGN_SETTINGS* m_designSettings;
BOARD* m_board;
DS_PROXY_VIEW_ITEM* m_drawingSheet;
NETLIST* m_schematicNetlist;
std::vector<DRC_RULE*> m_rules;
bool m_rulesValid;
std::vector<DRC_TEST_PROVIDER*> m_testProviders;
std::vector<std::shared_ptr<DRC_RULE>> m_rules;
bool m_rulesValid;
std::vector<DRC_TEST_PROVIDER*> m_testProviders;
EDA_UNITS m_userUnits;
std::vector<int> m_errorLimits;
bool m_reportAllTrackErrors;
bool m_testFootprints;
EDA_UNITS m_userUnits;
std::vector<int> m_errorLimits;
bool m_reportAllTrackErrors;
bool m_testFootprints;
// constraint -> rule -> provider
std::unordered_map<DRC_CONSTRAINT_T, std::vector<DRC_ENGINE_CONSTRAINT*>*> m_constraintMap;
DRC_VIOLATION_HANDLER m_violationHandler;
REPORTER* m_reporter;
PROGRESS_REPORTER* m_progressReporter;
DRC_VIOLATION_HANDLER m_violationHandler;
REPORTER* m_reporter;
PROGRESS_REPORTER* m_progressReporter;
wxString m_msg; // Allocating strings gets expensive enough to want to avoid it
std::shared_ptr<KIGFX::VIEW_OVERLAY> m_debugOverlay;

View File

@ -90,7 +90,7 @@ void DRC_RULES_PARSER::parseUnknown()
}
void DRC_RULES_PARSER::Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporter )
void DRC_RULES_PARSER::Parse( std::vector<std::shared_ptr<DRC_RULE>>& aRules, REPORTER* aReporter )
{
bool haveVersion = false;
wxString msg;
@ -146,7 +146,7 @@ void DRC_RULES_PARSER::Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporte
break;
case T_rule:
aRules.push_back( parseDRC_RULE() );
aRules.emplace_back( parseDRC_RULE() );
break;
case T_EOF:
@ -168,11 +168,12 @@ void DRC_RULES_PARSER::Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporte
}
DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE()
std::shared_ptr<DRC_RULE> DRC_RULES_PARSER::parseDRC_RULE()
{
DRC_RULE* rule = new DRC_RULE();
T token = NextTok();
wxString msg;
std::shared_ptr<DRC_RULE> rule = std::make_shared<DRC_RULE>();
T token = NextTok();
wxString msg;
if( !IsSymbol( token ) )
reportError( _( "Missing rule name." ) );
@ -189,7 +190,7 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE()
switch( token )
{
case T_constraint:
parseConstraint( rule );
parseConstraint( rule.get() );
break;
case T_condition:

View File

@ -43,10 +43,10 @@ public:
DRC_RULES_PARSER( const wxString& aSource, const wxString& aSourceDescr );
DRC_RULES_PARSER( FILE* aFile, const wxString& aFilename );
void Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporter );
void Parse( std::vector<std::shared_ptr<DRC_RULE>>& aRules, REPORTER* aReporter );
private:
DRC_RULE* parseDRC_RULE();
std::shared_ptr<DRC_RULE> parseDRC_RULE();
void parseConstraint( DRC_RULE* aRule );
void parseValueWithUnits( const wxString& aExpr, int& aResult );

View File

@ -78,6 +78,8 @@ PCB_MARKER::PCB_MARKER( std::shared_ptr<RC_ITEM> aItem, const VECTOR2I& aPositio
/* destructor */
PCB_MARKER::~PCB_MARKER()
{
if( m_rcItem )
m_rcItem->SetParent( nullptr );
}