From e73caa3b2c4b5fcf3e0e3ebc3ca03b3d00b08006 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Fri, 13 Feb 2026 20:37:48 -0800 Subject: [PATCH] Fix integer overflow crash in PADS ASCII importer The scaleSize(), scaleCoord(), and partCoordScaler functions cast 64-bit nanometer values to int without bounds checking. For MILS-unit files with large coordinates (e.g. 124,020 mils * 25,400 nm/mil = 3.15 billion nm), this exceeds INT_MAX and triggers undefined behavior, crashing in debug builds via KiROUND's overflow assertion and silently wrapping in release. Clamp all three conversion sites to [INT_MIN, INT_MAX] before casting. Also fix two pre-existing build errors from recent header optimization commits (missing netclass.h and component_class_manager.h includes). Fixes https://gitlab.com/kicad/code/kicad/-/issues/23054 --- .../component_class_cache_proxy.h | 1 + pcbnew/edit_track_width.cpp | 1 + pcbnew/pcb_io/pads/pcb_io_pads.cpp | 15 ++++++++------- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/pcbnew/component_classes/component_class_cache_proxy.h b/pcbnew/component_classes/component_class_cache_proxy.h index fd330892af..38e40dc131 100644 --- a/pcbnew/component_classes/component_class_cache_proxy.h +++ b/pcbnew/component_classes/component_class_cache_proxy.h @@ -22,6 +22,7 @@ #define PCBNEW_COMPONENT_CLASS_CACHE_PROXY_H #include +#include #include /* diff --git a/pcbnew/edit_track_width.cpp b/pcbnew/edit_track_width.cpp index 22731a2b76..0f123e8771 100644 --- a/pcbnew/edit_track_width.cpp +++ b/pcbnew/edit_track_width.cpp @@ -23,6 +23,7 @@ */ #include +#include #include #include #include diff --git a/pcbnew/pcb_io/pads/pcb_io_pads.cpp b/pcbnew/pcb_io/pads/pcb_io_pads.cpp index 480ccadfd4..f3f420697c 100644 --- a/pcbnew/pcb_io/pads/pcb_io_pads.cpp +++ b/pcbnew/pcb_io/pads/pcb_io_pads.cpp @@ -25,6 +25,7 @@ #include "pads_layer_mapper.h" #include +#include #include #include #include @@ -357,9 +358,10 @@ void PCB_IO_PADS::loadFootprints() long long res_nm = val_nm - origin_nm; - if( !is_x ) res_nm = -res_nm; + if( !is_x ) + res_nm = -res_nm; - return static_cast( res_nm ); + return static_cast( std::clamp( res_nm, INT_MIN, INT_MAX ) ); }; footprint->SetPosition( VECTOR2I( partCoordScaler( pads_part.location.x, true ), @@ -2158,7 +2160,8 @@ std::map PCB_IO_PADS::DefaultLayerMappingCallback( int PCB_IO_PADS::scaleSize( double aVal ) const { - return static_cast( m_unitConverter.ToNanometersSize( aVal ) ); + int64_t nm = m_unitConverter.ToNanometersSize( aVal ); + return static_cast( std::clamp( nm, INT_MIN, INT_MAX ) ); } @@ -2169,10 +2172,8 @@ int PCB_IO_PADS::scaleCoord( double aVal, bool aIsX ) const long long origin_nm = static_cast( std::round( origin * m_scaleFactor ) ); long long val_nm = static_cast( std::round( aVal * m_scaleFactor ) ); - if( aIsX ) - return static_cast( val_nm - origin_nm ); - else - return static_cast( origin_nm - val_nm ); + long long result = aIsX ? ( val_nm - origin_nm ) : ( origin_nm - val_nm ); + return static_cast( std::clamp( result, INT_MIN, INT_MAX ) ); }