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
This commit is contained in:
Seth Hillbrand
2026-02-13 20:37:48 -08:00
parent 2b04682b42
commit e73caa3b2c
3 changed files with 10 additions and 7 deletions
@@ -22,6 +22,7 @@
#define PCBNEW_COMPONENT_CLASS_CACHE_PROXY_H
#include <component_classes/component_class.h>
#include <component_classes/component_class_manager.h>
#include <footprint.h>
/*
+1
View File
@@ -23,6 +23,7 @@
*/
#include <board_design_settings.h>
#include <netclass.h>
#include <pcb_edit_frame.h>
#include <pcbnew_id.h>
#include <pcb_track.h>
+8 -7
View File
@@ -25,6 +25,7 @@
#include "pads_layer_mapper.h"
#include <algorithm>
#include <climits>
#include <cmath>
#include <fstream>
#include <functional>
@@ -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<int>( res_nm );
return static_cast<int>( std::clamp<long long>( res_nm, INT_MIN, INT_MAX ) );
};
footprint->SetPosition( VECTOR2I( partCoordScaler( pads_part.location.x, true ),
@@ -2158,7 +2160,8 @@ std::map<wxString, PCB_LAYER_ID> PCB_IO_PADS::DefaultLayerMappingCallback(
int PCB_IO_PADS::scaleSize( double aVal ) const
{
return static_cast<int>( m_unitConverter.ToNanometersSize( aVal ) );
int64_t nm = m_unitConverter.ToNanometersSize( aVal );
return static_cast<int>( std::clamp<int64_t>( 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<long long>( std::round( origin * m_scaleFactor ) );
long long val_nm = static_cast<long long>( std::round( aVal * m_scaleFactor ) );
if( aIsX )
return static_cast<int>( val_nm - origin_nm );
else
return static_cast<int>( origin_nm - val_nm );
long long result = aIsX ? ( val_nm - origin_nm ) : ( origin_nm - val_nm );
return static_cast<int>( std::clamp<long long>( result, INT_MIN, INT_MAX ) );
}