From 66b392cdcabdea7f470daa6dcfebeffef2d6f45a Mon Sep 17 00:00:00 2001 From: John Beard Date: Fri, 6 Dec 2024 20:18:21 +0800 Subject: [PATCH] Eeschema: avoid crash on save if a polyline is empty This normally should never happen, but could do in limited cases such as from bad imports or CI/testing inputs. It's probably still a bug in any real design usage, but assert and continue instead of crash. --- .../kicad_sexpr/sch_io_kicad_sexpr_common.cpp | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.cpp b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.cpp index 57d5b3be5a..843eda5b1d 100644 --- a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.cpp +++ b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_common.cpp @@ -309,29 +309,42 @@ void formatPoly( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aPolyLi { int newLine = 0; int lineCount = 1; + aFormatter->Print( aNestLevel, "(polyline%s\n", aIsPrivate ? " private" : "" ); aFormatter->Print( aNestLevel + 1, "(pts" ); - for( const VECTOR2I& pt : aPolyLine->GetPolyShape().Outline( 0 ).CPoints() ) - { - if( newLine == 4 || !ADVANCED_CFG::GetCfg().m_CompactSave ) - { - aFormatter->Print( 0, "\n" ); - aFormatter->Print( aNestLevel + 2, "(xy %s %s)", - EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.x ).c_str(), - EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.y ).c_str() ); - newLine = 0; - lineCount += 1; - } - else - { - aFormatter->Print( 0, " (xy %s %s)", - EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.x ).c_str(), - EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.y ).c_str() ); - } + const SHAPE_POLY_SET& polySet = aPolyLine->GetPolyShape(); - newLine += 1; + + if( polySet.OutlineCount() == 0 ) + { + // If we've managed to get a polyline with no points, that's probably a bad thing, + // but at least don't dereference it and crash. + wxFAIL_MSG( "Polyline has no outline" ); + } + else + { + for( const VECTOR2I& pt : polySet.Outline( 0 ).CPoints() ) + { + if( newLine == 4 || !ADVANCED_CFG::GetCfg().m_CompactSave ) + { + aFormatter->Print( 0, "\n" ); + aFormatter->Print( aNestLevel + 2, "(xy %s %s)", + EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.x ).c_str(), + EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.y ).c_str() ); + newLine = 0; + lineCount += 1; + } + else + { + aFormatter->Print( 0, " (xy %s %s)", + EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.x ).c_str(), + EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pt.y ).c_str() ); + } + + newLine += 1; + } } if( lineCount == 1 )