From e2bd76bdce739b4c329ca6f41cf8992e6207db7f Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop Date: Tue, 23 Jul 2024 01:40:56 +0300 Subject: [PATCH] Fix OOB access in LSET when opening a PCB file or updating from schematic. Fixes https://gitlab.com/kicad/code/kicad/-/issues/18422 --- common/lset.cpp | 5 +++-- include/base_set.h | 8 +++++++- include/lset.h | 4 ++-- qa/tests/common/test_lset.cpp | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/common/lset.cpp b/common/lset.cpp index c92c503827..668d5e3f08 100644 --- a/common/lset.cpp +++ b/common/lset.cpp @@ -41,14 +41,15 @@ LSET::LSET( std::initializer_list aList ) : - BASE_SET() + LSET() { for( PCB_LAYER_ID layer : aList ) set( layer ); } -LSET::LSET( const LSEQ& aSeq ) +LSET::LSET( const LSEQ& aSeq ) : + LSET() { for( PCB_LAYER_ID layer : aSeq ) set( layer ); diff --git a/include/base_set.h b/include/base_set.h index 7218365001..b3b59d26c8 100644 --- a/include/base_set.h +++ b/include/base_set.h @@ -42,7 +42,7 @@ public: using iterator = std::vector::iterator; using const_iterator = std::vector::const_iterator; - BASE_SET( size_t size = 64 ) : m_bits( size, 0 ) {} + BASE_SET( size_t size ) : m_bits( size, 0 ) {} bool test( size_t pos ) const { @@ -173,6 +173,8 @@ public: // Boolean operators BASE_SET& operator&=( const BASE_SET& rhs ) { + assert( m_bits.size() == rhs.m_bits.size() ); + for( size_t i = 0; i < m_bits.size(); ++i ) m_bits[i] &= rhs.m_bits[i]; @@ -181,6 +183,8 @@ public: BASE_SET& operator|=( const BASE_SET& rhs ) { + assert( m_bits.size() == rhs.m_bits.size() ); + for( size_t i = 0; i < m_bits.size(); ++i ) m_bits[i] |= rhs.m_bits[i]; @@ -189,6 +193,8 @@ public: BASE_SET& operator^=( const BASE_SET& rhs ) { + assert( m_bits.size() == rhs.m_bits.size() ); + for( size_t i = 0; i < m_bits.size(); ++i ) m_bits[i] ^= rhs.m_bits[i]; diff --git a/include/lset.h b/include/lset.h index 74e22676c1..2863a7889a 100644 --- a/include/lset.h +++ b/include/lset.h @@ -49,7 +49,7 @@ public: * Create an empty (cleared) set. */ LSET() : - BASE_SET(PCB_LAYER_ID_COUNT) // all bits are set to zero in BASE_SET() + BASE_SET( PCB_LAYER_ID_COUNT ) // all bits are set to zero in BASE_SET() { } @@ -59,7 +59,7 @@ public: } LSET( PCB_LAYER_ID aLayer ) : - BASE_SET(PCB_LAYER_ID_COUNT) + BASE_SET( PCB_LAYER_ID_COUNT ) { set( aLayer ); } diff --git a/qa/tests/common/test_lset.cpp b/qa/tests/common/test_lset.cpp index 4e974b7885..14e8bc2135 100644 --- a/qa/tests/common/test_lset.cpp +++ b/qa/tests/common/test_lset.cpp @@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE(LSETConstructorEmpty) // Initialize LSET from another BASE_SET BOOST_AUTO_TEST_CASE(LSETConstructorFromBaseSet) { - BASE_SET base; + BASE_SET base( PCB_LAYER_ID_COUNT ); base.set(F_Cu); base.set(In1_Cu);