Eagle: Fix NULL-dereference on malformed Eagle files

Eagle files that are edited may be missing required data.  While we do
not need to handle these files, we do need to prevent segfaults in KiCad
when reading them.
This commit is contained in:
Seth Hillbrand 2018-08-09 10:53:48 -07:00
parent e47351d1a6
commit 5bd959d92c
2 changed files with 40 additions and 17 deletions

View File

@ -469,8 +469,9 @@ void SCH_EAGLE_PLUGIN::loadDrawing( wxXmlNode* aDrawingNode )
// wxXmlNode* grid = drawingChildren["grid"] // wxXmlNode* grid = drawingChildren["grid"]
wxXmlNode* layers = drawingChildren["layers"]; auto layers = drawingChildren["layers"];
if( layers )
loadLayerDefs( layers ); loadLayerDefs( layers );
// wxXmlNode* library = drawingChildren["library"] // wxXmlNode* library = drawingChildren["library"]
@ -479,7 +480,9 @@ void SCH_EAGLE_PLUGIN::loadDrawing( wxXmlNode* aDrawingNode )
// Load schematic // Load schematic
loadSchematic( drawingChildren["schematic"] ); auto schematic = drawingChildren["schematic"];
if( schematic )
loadSchematic( schematic );
} }
@ -488,7 +491,8 @@ void SCH_EAGLE_PLUGIN::countNets( wxXmlNode* aSchematicNode )
// Map all children into a readable dictionary // Map all children into a readable dictionary
NODE_MAP schematicChildren = MapChildren( aSchematicNode ); NODE_MAP schematicChildren = MapChildren( aSchematicNode );
// Loop through all the sheets // Loop through all the sheets
wxXmlNode* sheetNode = schematicChildren["sheets"]->GetChildren();
wxXmlNode* sheetNode = getChildrenNodes( schematicChildren, "sheets" );
while( sheetNode ) while( sheetNode )
{ {
@ -519,8 +523,12 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
{ {
// Map all children into a readable dictionary // Map all children into a readable dictionary
NODE_MAP schematicChildren = MapChildren( aSchematicNode ); NODE_MAP schematicChildren = MapChildren( aSchematicNode );
auto partNode = getChildrenNodes( schematicChildren, "parts" );
auto libraryNode = getChildrenNodes( schematicChildren, "libraries" );
auto sheetNode = getChildrenNodes( schematicChildren, "sheets" );
wxXmlNode* partNode = schematicChildren["parts"]->GetChildren(); if( !partNode || !libraryNode || !sheetNode )
return;
while( partNode ) while( partNode )
{ {
@ -529,10 +537,7 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
partNode = partNode->GetNext(); partNode = partNode->GetNext();
} }
// Loop through all the libraries // Loop through all the libraries
wxXmlNode* libraryNode = schematicChildren["libraries"]->GetChildren();
while( libraryNode ) while( libraryNode )
{ {
// Read the library name // Read the library name
@ -553,9 +558,7 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
countNets( aSchematicNode ); countNets( aSchematicNode );
// Loop through all the sheets // Loop through all the sheets
wxXmlNode* sheetNode = schematicChildren["sheets"]->GetChildren(); int sheet_count = countChildren( sheetNode->GetParent(), "sheet" );
int sheet_count = countChildren( schematicChildren["sheets"], "sheet" );
// If eagle schematic has multiple sheets then create corresponding subsheets on the root sheet // If eagle schematic has multiple sheets then create corresponding subsheets on the root sheet
if( sheet_count > 1 ) if( sheet_count > 1 )
@ -1264,7 +1267,7 @@ EAGLE_LIBRARY* SCH_EAGLE_PLUGIN::loadLibrary( wxXmlNode* aLibraryNode,
NODE_MAP libraryChildren = MapChildren( aLibraryNode ); NODE_MAP libraryChildren = MapChildren( aLibraryNode );
// Loop through the symbols and load each of them // Loop through the symbols and load each of them
wxXmlNode* symbolNode = libraryChildren["symbols"]->GetChildren(); wxXmlNode* symbolNode = getChildrenNodes( libraryChildren, "symbols" );
while( symbolNode ) while( symbolNode )
{ {
@ -1274,7 +1277,7 @@ EAGLE_LIBRARY* SCH_EAGLE_PLUGIN::loadLibrary( wxXmlNode* aLibraryNode,
} }
// Loop through the devicesets and load each of them // Loop through the devicesets and load each of them
wxXmlNode* devicesetNode = libraryChildren["devicesets"]->GetChildren(); wxXmlNode* devicesetNode = getChildrenNodes( libraryChildren, "devicesets" );
while( devicesetNode ) while( devicesetNode )
{ {

View File

@ -376,15 +376,21 @@ void EAGLE_PLUGIN::loadAllSections( wxXmlNode* aDoc )
void EAGLE_PLUGIN::loadDesignRules( wxXmlNode* aDesignRules ) void EAGLE_PLUGIN::loadDesignRules( wxXmlNode* aDesignRules )
{
if( aDesignRules )
{ {
m_xpath->push( "designrules" ); m_xpath->push( "designrules" );
m_rules->parse( aDesignRules ); m_rules->parse( aDesignRules );
m_xpath->pop(); // "designrules" m_xpath->pop(); // "designrules"
} }
}
void EAGLE_PLUGIN::loadLayerDefs( wxXmlNode* aLayers ) void EAGLE_PLUGIN::loadLayerDefs( wxXmlNode* aLayers )
{ {
if( !aLayers )
return;
ELAYERS cu; // copper layers ELAYERS cu; // copper layers
// Get the first layer and iterate // Get the first layer and iterate
@ -456,6 +462,9 @@ void EAGLE_PLUGIN::loadLayerDefs( wxXmlNode* aLayers )
void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics ) void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
{ {
if( !aGraphics )
return;
m_xpath->push( "plain" ); m_xpath->push( "plain" );
// Get the first graphic and iterate // Get the first graphic and iterate
@ -780,11 +789,16 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
void EAGLE_PLUGIN::loadLibrary( wxXmlNode* aLib, const wxString* aLibName ) void EAGLE_PLUGIN::loadLibrary( wxXmlNode* aLib, const wxString* aLibName )
{ {
m_xpath->push( "packages" ); if( !aLib || !aLibName )
return;
// library will have <xmlattr> node, skip that and get the single packages node // library will have <xmlattr> node, skip that and get the single packages node
wxXmlNode* packages = MapChildren( aLib )["packages"]; wxXmlNode* packages = MapChildren( aLib )["packages"];
if( !packages )
return;
m_xpath->push( "packages" );
// Create a MODULE for all the eagle packages, for use later via a copy constructor // Create a MODULE for all the eagle packages, for use later via a copy constructor
// to instantiate needed MODULES in our BOARD. Save the MODULE templates in // to instantiate needed MODULES in our BOARD. Save the MODULE templates in
@ -836,6 +850,9 @@ void EAGLE_PLUGIN::loadLibrary( wxXmlNode* aLib, const wxString* aLibName )
void EAGLE_PLUGIN::loadLibraries( wxXmlNode* aLibs ) void EAGLE_PLUGIN::loadLibraries( wxXmlNode* aLibs )
{ {
if( !aLibs )
return;
m_xpath->push( "libraries.library", "name" ); m_xpath->push( "libraries.library", "name" );
// Get the first library and iterate // Get the first library and iterate
@ -856,6 +873,9 @@ void EAGLE_PLUGIN::loadLibraries( wxXmlNode* aLibs )
void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements ) void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements )
{ {
if( !aElements )
return;
m_xpath->push( "elements.element", "name" ); m_xpath->push( "elements.element", "name" );
EATTR name; EATTR name;