From 9805aca5a088781f9d1f60f86e79b80dd7771d69 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sat, 30 Sep 2023 14:54:25 +0100 Subject: [PATCH] Handle backslash-escaped quotes in libeval. Fixes https://gitlab.com/kicad/code/kicad/-/issues/15786 --- common/libeval_compiler/libeval_compiler.cpp | 23 ++++++++++++++---- include/libeval_compiler/libeval_compiler.h | 2 ++ pcbnew/drc/drc_engine.cpp | 25 +++++++++++++------- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/common/libeval_compiler/libeval_compiler.cpp b/common/libeval_compiler/libeval_compiler.cpp index 15622b2e2a..090b4d0a06 100644 --- a/common/libeval_compiler/libeval_compiler.cpp +++ b/common/libeval_compiler/libeval_compiler.cpp @@ -201,6 +201,24 @@ wxString UCODE::Dump() const }; +wxString TOKENIZER::GetString() +{ + wxString rv; + + while( m_pos < m_str.length() && m_str[ m_pos ] != '\'' ) + { + if( m_str[ m_pos ] == '\\' && m_pos + 1 < m_str.length() && m_str[ m_pos + 1 ] == '\'' ) + m_pos++; + + rv.append( 1, m_str[ m_pos++ ] ); + } + + m_pos++; + + return rv; +} + + wxString TOKENIZER::GetChars( const std::function& cond ) const { wxString rv; @@ -383,12 +401,9 @@ T_TOKEN COMPILER::getToken() bool COMPILER::lexString( T_TOKEN& aToken ) { - wxString str = m_tokenizer.GetChars( []( int c ) -> bool { return c != '\''; } ); - aToken.token = G_STRING; - aToken.value.str = new wxString( str ); + aToken.value.str = new wxString( m_tokenizer.GetString() ); - m_tokenizer.NextChar( str.length() + 1 ); m_lexerState = LS_DEFAULT; return true; } diff --git a/include/libeval_compiler/libeval_compiler.h b/include/libeval_compiler/libeval_compiler.h index 3fd1ed0ba1..db80ccb0c9 100644 --- a/include/libeval_compiler/libeval_compiler.h +++ b/include/libeval_compiler/libeval_compiler.h @@ -474,6 +474,8 @@ public: return m_pos; } + wxString GetString(); + wxString GetChars( const std::function& cond ) const; bool MatchAhead( const wxString& match, diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index fd3c07c444..0f64559fda 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -229,13 +229,21 @@ void DRC_ENGINE::loadImplicitRules() auto makeNetclassRules = [&]( const std::shared_ptr& nc, bool isDefault ) { - wxString ncName = nc->GetName(); - wxString expr; + wxString ncName = nc->GetName(); + wxString friendlyName; + wxString* shownName = &ncName; + wxString expr; + + if( ncName.Replace( "'", "\\'" ) ) + { + friendlyName = nc->GetName(); + shownName = &friendlyName; + } if( nc->GetClearance() || nc->GetTrackWidth() ) { std::shared_ptr netclassRule = std::make_shared(); - netclassRule->m_Name = wxString::Format( _( "netclass '%s'" ), ncName ); + netclassRule->m_Name = wxString::Format( _( "netclass '%s'" ), *shownName ); netclassRule->m_Implicit = true; expr = wxString::Format( wxT( "A.NetClass == '%s'" ), ncName ); @@ -262,7 +270,7 @@ void DRC_ENGINE::loadImplicitRules() { std::shared_ptr netclassRule = std::make_shared(); netclassRule->m_Name = wxString::Format( _( "netclass '%s' (diff pair)" ), - ncName ); + *shownName ); netclassRule->m_Implicit = true; expr = wxString::Format( wxT( "A.NetClass == '%s' && A.inDiffPair('*')" ), @@ -280,7 +288,7 @@ void DRC_ENGINE::loadImplicitRules() { std::shared_ptr netclassRule = std::make_shared(); netclassRule->m_Name = wxString::Format( _( "netclass '%s' (diff pair)" ), - ncName ); + *shownName ); netclassRule->m_Implicit = true; expr = wxString::Format( wxT( "A.NetClass == '%s'" ), ncName ); @@ -297,7 +305,7 @@ void DRC_ENGINE::loadImplicitRules() { netclassRule = std::make_shared(); netclassRule->m_Name = wxString::Format( _( "netclass '%s' (diff pair)" ), - ncName ); + *shownName ); netclassRule->m_Implicit = true; expr = wxString::Format( wxT( "A.NetClass == '%s' && AB.isCoupledDiffPair()" ), @@ -314,7 +322,7 @@ void DRC_ENGINE::loadImplicitRules() if( nc->GetViaDiameter() || nc->GetViaDrill() ) { std::shared_ptr netclassRule = std::make_shared(); - netclassRule->m_Name = wxString::Format( _( "netclass '%s'" ), ncName ); + netclassRule->m_Name = wxString::Format( _( "netclass '%s'" ), *shownName ); netclassRule->m_Implicit = true; expr = wxString::Format( wxT( "A.NetClass == '%s' && A.Via_Type != 'Micro'" ), @@ -342,7 +350,8 @@ void DRC_ENGINE::loadImplicitRules() if( nc->GetuViaDiameter() || nc->GetuViaDrill() ) { std::shared_ptr netclassRule = std::make_shared(); - netclassRule->m_Name = wxString::Format( _( "netclass '%s' (uvia)" ), ncName ); + netclassRule->m_Name = wxString::Format( _( "netclass '%s' (uvia)" ), + *shownName ); netclassRule->m_Implicit = true; expr = wxString::Format( wxT( "A.NetClass == '%s' && A.Via_Type == 'Micro'" ),