Fix issue in aperture macro with some strange gerber files.

Fixes: lp:1755623
https://bugs.launchpad.net/kicad/+bug/1755623
This commit is contained in:
jean-pierre charras 2018-03-14 14:55:51 +01:00
parent 66d5d10b49
commit fa41026f36
3 changed files with 83 additions and 80 deletions

View File

@ -179,79 +179,84 @@ bool AM_PARAM::ReadParam( char*& aText )
{ {
switch( *aText ) switch( *aText )
{ {
case ',': case ',':
aText++;
if( !found ) // happens when a string starts by ',' before any param
break; // just skip this separator
// fall through
case '\n':
case '\r':
case 0: // EOL
case '*': // Terminator in a gerber command
end = true;
break;
case ' ':
aText++;
break;
case '$':
// defered value defined later, in ADD command which define defered parameters
++aText;
ivalue = ReadInt( aText, false );
if( m_index < 1 )
SetIndex( ivalue );
PushOperator( PUSHPARM, ivalue );
found = true;
break;
case '/':
PushOperator( DIV );
aText++;
break;
case '(': // Open a block to evaluate an expression between '(' and ')'
PushOperator( OPEN_PAR );
aText++;
break;
case ')': // close a block between '(' and ')'
PushOperator( CLOSE_PAR );
aText++;
break;
case 'x':
case 'X':
PushOperator( MUL );
aText++;
break;
case '-':
case '+':
// Test if this is an operator between 2 params, or the sign of a value
if( m_paramStack.size() > 0 && !m_paramStack.back().IsOperator() )
{ // Seems an operator
PushOperator( *aText == '+' ? ADD : SUB );
aText++; aText++;
// fall through }
case 0: // EOL else
case '*': // Terminator in a gerber command { // seems the sign of a value
end = true;
break;
case ' ':
aText++;
break;
case '$':
// defered value defined later, in ADD command which define defered parameters
++aText;
ivalue = ReadInt( aText, false );
if( m_index < 1 )
SetIndex( ivalue );
PushOperator( PUSHPARM, ivalue );
found = true;
break;
case '/':
PushOperator( DIV );
aText++;
break;
case '(': // Open a block to evaluate an expression between '(' and ')'
PushOperator( OPEN_PAR );
aText++;
break;
case ')': // close a block between '(' and ')'
PushOperator( CLOSE_PAR );
aText++;
break;
case 'x':
case 'X':
PushOperator( MUL );
aText++;
break;
case '-':
case '+':
// Test if this is an operator between 2 params, or the sign of a value
if( m_paramStack.size() > 0 && !m_paramStack.back().IsOperator() )
{ // Seems an operator
PushOperator( *aText == '+' ? ADD : SUB );
aText++;
}
else
{ // seems the sign of a value
dvalue = ReadDouble( aText, false );
PushOperator( PUSHVALUE, dvalue );
found = true;
}
break;
case '=': // A local definition found like $4=$3/2
// At this point, one defered parameter is expected to be read.
// this parameter value (the index) is stored in m_index.
// The list of items is cleared
aText++;
m_paramStack.clear();
found = false;
break;
default:
dvalue = ReadDouble( aText, false ); dvalue = ReadDouble( aText, false );
PushOperator( PUSHVALUE, dvalue ); PushOperator( PUSHVALUE, dvalue );
found = true; found = true;
break; }
break;
case '=': // A local definition found like $4=$3/2
// At this point, one defered parameter is expected to be read.
// this parameter value (the index) is stored in m_index.
// The list of items is cleared
aText++;
m_paramStack.clear();
found = false;
break;
default:
dvalue = ReadDouble( aText, false );
PushOperator( PUSHVALUE, dvalue );
found = true;
break;
} }
} }

View File

@ -104,12 +104,11 @@ bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName )
/** // size of a single line of text from a gerber file.
* size of single line of a text from a gerber file. // warning: some files can have *very long* lines, so the buffer must be large.
* warning: some files can have *very long* lines, so the buffer must be large.
*/
#define GERBER_BUFZ 1000000 #define GERBER_BUFZ 1000000
static char line[GERBER_BUFZ]; // A large buffer to store one line
static char lineBuffer[GERBER_BUFZ+1];
bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName ) bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
{ {
@ -134,11 +133,11 @@ bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
while( true ) while( true )
{ {
if( fgets( line, sizeof(line), m_Current_File ) == NULL ) if( fgets( lineBuffer, GERBER_BUFZ, m_Current_File ) == NULL )
break; break;
m_LineNum++; m_LineNum++;
text = StrPurge( line ); text = StrPurge( lineBuffer );
while( text && *text ) while( text && *text )
{ {
@ -195,7 +194,7 @@ bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
if( m_CommandState != ENTER_RS274X_CMD ) if( m_CommandState != ENTER_RS274X_CMD )
{ {
m_CommandState = ENTER_RS274X_CMD; m_CommandState = ENTER_RS274X_CMD;
ReadRS274XCommand( line, GERBER_BUFZ, text ); ReadRS274XCommand( lineBuffer, GERBER_BUFZ, text );
} }
else //Error else //Error
{ {

View File

@ -1086,13 +1086,13 @@ bool GERBER_FILE_IMAGE::ReadApertureMacro( char *aBuff, unsigned int aBuffSize,
prim.primitive_id = (AM_PRIMITIVE_ID) primitive_type; prim.primitive_id = (AM_PRIMITIVE_ID) primitive_type;
int ii; int ii;
for( ii = 0; ii < *aText && *aText != '*'; ++ii ) for( ii = 0; ii < paramCount && *aText && *aText != '*'; ++ii )
{ {
prim.params.push_back( AM_PARAM() ); prim.params.push_back( AM_PARAM() );
AM_PARAM& param = prim.params.back(); AM_PARAM& param = prim.params.back();
aText = GetNextLine( aBuff, aBuffSize, aText, gerber_file ); aText = GetNextLine( aBuff, aBuffSize, aText, gerber_file );
if( aText == NULL) // End of File if( aText == NULL) // End of File
return false; return false;
@ -1106,7 +1106,6 @@ bool GERBER_FILE_IMAGE::ReadApertureMacro( char *aBuff, unsigned int aBuffSize,
msg.Printf( wxT( "RS274X: read macro descr type %d: read %d parameters, insufficient parameters\n" ), msg.Printf( wxT( "RS274X: read macro descr type %d: read %d parameters, insufficient parameters\n" ),
prim.primitive_id, ii ); prim.primitive_id, ii );
AddMessageToList( msg ); AddMessageToList( msg );
} }
// there are more parameters to read if this is an AMP_OUTLINE // there are more parameters to read if this is an AMP_OUTLINE
if( prim.primitive_id == AMP_OUTLINE ) if( prim.primitive_id == AMP_OUTLINE )