From 4d2d70ce220f30bacf3a4545d9ead8f8cd9fd40c Mon Sep 17 00:00:00 2001 From: John Beard Date: Sun, 24 Nov 2024 13:29:19 +0800 Subject: [PATCH] Fabmaster: catch illegal parses up front Parsing an empty string as double/int produces uninitialised data. That is likely to cause an undefined amout of chaos later on, so catch it explicitly with a wxCHECK. It's still something that shouldn't happen, and could still cause chaos, but it's at least deterministic. It also avoids putting gigantic numbers into things that don't expect them. For example normalising an angle of 1e303 is functionally an infinite loop. This happens at least in files with missing fields in rows, like in #19174's file, line 4: S!U2306!IC!!!!!!SOT_23_5!!!!!SGM2576/TT9107!!! The file is still broken, but now it loads. Relates-To: https://gitlab.com/kicad/code/kicad/-/issues/19174 --- pcbnew/pcb_io/fabmaster/import_fabmaster.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pcbnew/pcb_io/fabmaster/import_fabmaster.cpp b/pcbnew/pcb_io/fabmaster/import_fabmaster.cpp index e38357f035..386b9e19a1 100644 --- a/pcbnew/pcb_io/fabmaster/import_fabmaster.cpp +++ b/pcbnew/pcb_io/fabmaster/import_fabmaster.cpp @@ -86,6 +86,9 @@ void FABMASTER::checkpoint() double FABMASTER::readDouble( const std::string& aStr ) const { + // This is bad, but at least don't return uninitialized data + wxCHECK_MSG( !aStr.empty(), 0.0, "Empty string passed to readDouble" ); + std::istringstream istr( aStr ); istr.imbue( std::locale::classic() ); @@ -97,6 +100,9 @@ double FABMASTER::readDouble( const std::string& aStr ) const int FABMASTER::readInt( const std::string& aStr ) const { + // This is bad, but at least don't return uninitialized data + wxCHECK_MSG( !aStr.empty(), 0, "Empty string passed to readInt" ); + std::istringstream istr( aStr ); istr.imbue( std::locale::classic() ); @@ -108,7 +114,6 @@ int FABMASTER::readInt( const std::string& aStr ) const bool FABMASTER::Read( const std::string& aFile ) { - std::ifstream ifs( aFile, std::ios::in | std::ios::binary ); if( !ifs.is_open() )