7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-02 00:26:45 +00:00

Fix creation of Altium compound files from IntLibs

A previous change introduced an invalid cast from
base to derived class.  To clean this up, changed
DecodeIntLibStream to have an out param and allow
two-step initialization of ALTIUM_COMPOUND_FILE

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20099
This commit is contained in:
Jon Evans 2025-02-25 22:34:26 -05:00
parent 41f5750be7
commit b6aac9369e
4 changed files with 40 additions and 16 deletions

View File

@ -47,6 +47,11 @@ std::string FormatPath( const std::vector<std::string>& aVectorPath )
}
ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE()
{
}
ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath )
{
// Open file
@ -91,6 +96,12 @@ ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath )
ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const void* aBuffer, size_t aLen )
{
InitFromBuffer( aBuffer, aLen );
}
void ALTIUM_COMPOUND_FILE::InitFromBuffer( const void* aBuffer, size_t aLen )
{
m_buffer.resize( aLen );
memcpy( m_buffer.data(), aBuffer, aLen );
@ -106,10 +117,11 @@ ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const void* aBuffer, size_t aLen )
}
std::unique_ptr<ALTIUM_COMPOUND_FILE>
ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe )
bool ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe,
ALTIUM_COMPOUND_FILE* aOutput )
{
wxCHECK( cfe.size >= 1, nullptr );
wxCHECK( aOutput, false );
wxCHECK( cfe.size >= 1, false );
size_t streamSize = cfe.size;
wxMemoryBuffer buffer( streamSize );
@ -130,14 +142,13 @@ ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe )
decodedPcbLibStream << zlibInputStream;
wxStreamBuffer* outStream = decodedPcbLibStream.GetOutputStreamBuffer();
return std::make_unique<ALTIUM_COMPOUND_FILE>( outStream->GetBufferStart(),
outStream->GetIntPosition() );
aOutput->InitFromBuffer( outStream->GetBufferStart(), outStream->GetIntPosition() );
return true;
}
else if( buffer[0] == 0x00 )
{
return std::make_unique<ALTIUM_COMPOUND_FILE>(
reinterpret_cast<uint8_t*>( buffer.GetData() ) + 1, streamSize - 1 );
aOutput->InitFromBuffer( static_cast<uint8_t*>( buffer.GetData() ) + 1, streamSize - 1 );
return true;
}
else
{
@ -145,7 +156,7 @@ ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe )
buffer[0], buffer[1], buffer[2], buffer[3], buffer[4] ) );
}
return nullptr;
return false;
}

View File

@ -70,6 +70,9 @@ class ALTIUM_COMPOUND_FILE
friend class ALTIUM_PCB_COMPOUND_FILE;
public:
/// Create an uninitialized file for two-step initialization (e.g. with InitFromBuffer)
ALTIUM_COMPOUND_FILE();
/**
* Open a CFB file. Constructor might throw an IO_ERROR.
*
@ -90,9 +93,18 @@ public:
ALTIUM_COMPOUND_FILE& operator=( const ALTIUM_COMPOUND_FILE& temp_obj ) = delete;
~ALTIUM_COMPOUND_FILE() = default;
/**
* Load a CFB file from memory; may throw an IO_ERROR.
* Data is copied.
*
* @param aBuffer data buffer
* @param aLen data length
*/
void InitFromBuffer( const void* aBuffer, size_t aLen );
const CFB::CompoundFileReader& GetCompoundFileReader() const { return *m_reader; }
std::unique_ptr<ALTIUM_COMPOUND_FILE> DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe );
bool DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe, ALTIUM_COMPOUND_FILE* aOutput );
const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::vector<std::string>& aStreamPath ) const;

View File

@ -32,6 +32,8 @@
class ALTIUM_PCB_COMPOUND_FILE : public ALTIUM_COMPOUND_FILE
{
public:
ALTIUM_PCB_COMPOUND_FILE() : ALTIUM_COMPOUND_FILE() {}
ALTIUM_PCB_COMPOUND_FILE( const wxString& aFilePath );
ALTIUM_PCB_COMPOUND_FILE( const void* aBuffer, size_t aLen );
~ALTIUM_PCB_COMPOUND_FILE();

View File

@ -197,14 +197,13 @@ void PCB_IO_ALTIUM_DESIGNER::loadAltiumLibrary( const wxString& aLibraryPath )
std::map<wxString, const CFB::COMPOUND_FILE_ENTRY*> pcbLibFiles =
intCom->EnumDir( L"PCBLib" );
for( const auto& [pcbLibName, pcbCfe] : pcbLibFiles )
{
auto decodedStream = intCom->DecodeIntLibStream( *pcbCfe );
m_fplibFiles[aLibraryPath].push_back(
std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE>(
static_cast<ALTIUM_PCB_COMPOUND_FILE*>(decodedStream.release())
)
);
auto decodedStream = std::make_unique<ALTIUM_PCB_COMPOUND_FILE>();
if( intCom->DecodeIntLibStream( *pcbCfe, decodedStream.get() ) )
m_fplibFiles[aLibraryPath].emplace_back( std::move( decodedStream ) );
}
}
}