From 1b1bf8a17bf166e08f911dd2ee15c2654cbcfbae Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Wed, 8 Dec 2021 15:50:33 -0800 Subject: [PATCH] Better handling of escaped characters in STEP parser Fixes https://gitlab.com/kicad/code/kicad/issues/9897 --- libs/sexpr/sexpr_parser.cpp | 43 ++++++++++++++++------------ utils/kicad2step/pcb/3d_resolver.cpp | 2 +- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/libs/sexpr/sexpr_parser.cpp b/libs/sexpr/sexpr_parser.cpp index 45f4420852..b454656d70 100644 --- a/libs/sexpr/sexpr_parser.cpp +++ b/libs/sexpr/sexpr_parser.cpp @@ -122,29 +122,36 @@ namespace SEXPR } else if( *it == '"' ) { - size_t startPos = std::distance(aString.begin(), it) + 1; - size_t closingPos = startPos > 0 ? startPos - 1 : startPos; + ++it; - // find the closing quote character, be sure it is not escaped - do + auto starting_it = it; + + for( ; it != aString.end(); ++it ) { - closingPos = aString.find_first_of( '"', closingPos + 1 ); + auto ch = *it; + + if( ch == '\\' ) + { + // Skip the next escaped character + if( ++it == aString.end() ) + break; + + continue; + } + + if( ch == '"' ) + break; } - while( closingPos != std::string::npos - && ( closingPos > 0 && aString[closingPos - 1] == '\\' ) ); - if( closingPos != std::string::npos ) - { - auto str = std::make_unique( - aString.substr( startPos, closingPos - startPos ), m_lineNumber ); - std::advance( it, closingPos - startPos + 2 ); - - return str; - } - else - { + if( it == aString.end() ) throw PARSE_EXCEPTION("missing closing quote"); - } + + auto str = std::make_unique( std::string( starting_it, it ), + m_lineNumber ); + + ++it; + return str; + } else { diff --git a/utils/kicad2step/pcb/3d_resolver.cpp b/utils/kicad2step/pcb/3d_resolver.cpp index 73ec20f9ad..bc7040f4d1 100644 --- a/utils/kicad2step/pcb/3d_resolver.cpp +++ b/utils/kicad2step/pcb/3d_resolver.cpp @@ -184,7 +184,7 @@ wxString S3D_RESOLVER::ResolvePath( const wxString& aFileName, // been checked. This case accounts for partial paths which do not contain ${KIPRJMOD}. // This check is performed before checking the path relative to ${KICAD6_3DMODEL_DIR} so that // users can potentially override a model within ${KICAD6_3DMODEL_DIR}. - if( !m_Paths.begin()->m_Pathexp.empty() && !tname.StartsWith( ":" ) ) + if( !m_Paths.empty() && !m_Paths.begin()->m_Pathexp.empty() && !tname.StartsWith( ":" ) ) { tmpFN.Assign( m_Paths.begin()->m_Pathexp, "" ); wxString fullPath = tmpFN.GetPathWithSep() + tname;