Make 3D path resolvers agnostic about alias syntax.

Some code seems to think it's :alias:path while other code thinks it's
alias:path.  This commit updates both the Kicad2Step resolver and the
KiCad internal resolver to be agnostic.

In 7.0 we should probably get rid of aliases entirely.  But that's a
story for another day....

Fixes https://gitlab.com/kicad/code/kicad/issues/9002
This commit is contained in:
Jeff Young 2021-09-06 14:24:23 +01:00
parent 0321e55f0b
commit c861fadc31
2 changed files with 63 additions and 35 deletions

View File

@ -845,18 +845,20 @@ bool FILENAME_RESOLVER::SplitAlias( const wxString& aFileName,
anAlias.clear(); anAlias.clear();
aRelPath.clear(); aRelPath.clear();
if( !aFileName.StartsWith( wxT( ":" ) ) ) size_t searchStart = 0;
return false;
size_t tagpos = aFileName.find( wxT( ":" ), 1 ); if( aFileName.StartsWith( wxT( ":" ) ) )
searchStart = 1;
if( wxString::npos == tagpos || 1 == tagpos ) size_t tagpos = aFileName.find( wxT( ":" ), searchStart );
if( tagpos == wxString::npos || tagpos == searchStart )
return false; return false;
if( tagpos + 1 >= aFileName.length() ) if( tagpos + 1 >= aFileName.length() )
return false; return false;
anAlias = aFileName.substr( 1, tagpos - 1 ); anAlias = aFileName.substr( searchStart, tagpos - searchStart );
aRelPath = aFileName.substr( tagpos + 1 ); aRelPath = aFileName.substr( tagpos + 1 );
return true; return true;
@ -971,46 +973,69 @@ bool FILENAME_RESOLVER::ValidateFileName( const wxString& aFileName, bool& hasAl
return false; return false;
wxString filename = aFileName; wxString filename = aFileName;
size_t pos0 = aFileName.find( ':' ); wxString lpath;
size_t aliasStart = aFileName.starts_with( ':' ) ? 1 : 0;
size_t aliasEnd = aFileName.find( ':', aliasStart );
// ensure that the file separators suit the current platform // ensure that the file separators suit the current platform
#ifdef __WINDOWS__ #ifdef __WINDOWS__
filename.Replace( wxT( "/" ), wxT( "\\" ) ); filename.Replace( wxT( "/" ), wxT( "\\" ) );
// if we see the :\ pattern then it must be a drive designator // if we see the :\ pattern then it must be a drive designator
if( pos0 != wxString::npos ) if( aliasEnd != wxString::npos )
{ {
size_t pos1 = filename.find( wxT( ":\\" ) ); size_t pos1 = filename.find( wxT( ":\\" ) );
if( pos1 != wxString::npos && ( pos1 != pos0 || pos1 != 1 ) ) if( pos1 != wxString::npos && ( pos1 != aliasEnd || pos1 != 1 ) )
return false; return false;
// if we have a drive designator then we have no alias // if we have a drive designator then we have no alias
if( pos1 != wxString::npos ) if( pos1 != wxString::npos )
pos0 = wxString::npos; aliasEnd = wxString::npos;
} }
#else #else
filename.Replace( wxT( "\\" ), wxT( "/" ) ); filename.Replace( wxT( "\\" ), wxT( "/" ) );
#endif #endif
// names may not end with ':' // names may not end with ':'
if( pos0 == aFileName.length() -1 ) if( aliasEnd == aFileName.length() -1 )
return false; return false;
if( pos0 != wxString::npos ) if( aliasEnd != wxString::npos )
{ {
// ensure the alias component is not empty // ensure the alias component is not empty
if( pos0 == 0 ) if( aliasEnd == aliasStart )
return false; return false;
wxString lpath = filename.substr( 0, pos0 ); lpath = filename.substr( aliasStart, aliasEnd );
// check the alias for restricted characters // check the alias for restricted characters
if( wxString::npos != lpath.find_first_of( wxT( "{}[]()%~<>\"='`;:.,&?/\\|$" ) ) ) if( wxString::npos != lpath.find_first_of( wxT( "{}[]()%~<>\"='`;:.,&?/\\|$" ) ) )
return false; return false;
hasAlias = true; hasAlias = true;
lpath = aFileName.substr( aliasEnd + 1 );
} }
else
{
lpath = aFileName;
// in the case of ${ENV_VAR}|$(ENV_VAR)/path, strip the
// environment string before testing
aliasEnd = wxString::npos;
if( aFileName.StartsWith( "${" ) )
aliasEnd = aFileName.find( '}' );
else if( aFileName.StartsWith( "$(" ) )
aliasEnd = aFileName.find( ')' );
if( aliasEnd != wxString::npos )
lpath = aFileName.substr( aliasEnd + 1 );
}
if( wxString::npos != lpath.find_first_of( wxFileName::GetForbiddenChars() ) )
return false;
return true; return true;
} }

View File

@ -792,18 +792,20 @@ bool S3D_RESOLVER::SplitAlias( const wxString& aFileName, wxString& anAlias, wxS
anAlias.clear(); anAlias.clear();
aRelPath.clear(); aRelPath.clear();
if( !aFileName.StartsWith( ":" ) ) size_t searchStart = 0;
return false;
size_t tagpos = aFileName.find( ":", 1 ); if( aFileName.StartsWith( wxT( ":" ) ) )
searchStart = 1;
if( wxString::npos == tagpos || 1 == tagpos ) size_t tagpos = aFileName.find( wxT( ":" ), searchStart );
if( tagpos == wxString::npos || tagpos == searchStart )
return false; return false;
if( tagpos + 1 >= aFileName.length() ) if( tagpos + 1 >= aFileName.length() )
return false; return false;
anAlias = aFileName.substr( 1, tagpos - 1 ); anAlias = aFileName.substr( searchStart, tagpos - searchStart );
aRelPath = aFileName.substr( tagpos + 1 ); aRelPath = aFileName.substr( tagpos + 1 );
return true; return true;
@ -907,46 +909,47 @@ bool S3D_RESOLVER::ValidateFileName( const wxString& aFileName, bool& hasAlias )
wxString filename = aFileName; wxString filename = aFileName;
wxString lpath; wxString lpath;
size_t pos0 = aFileName.find( ':' ); size_t aliasStart = aFileName.starts_with( ':' ) ? 1 : 0;
size_t aliasEnd = aFileName.find( ':' );
// ensure that the file separators suit the current platform // ensure that the file separators suit the current platform
#ifdef __WINDOWS__ #ifdef __WINDOWS__
filename.Replace( "/", "\\" ); filename.Replace( "/", "\\" );
// if we see the :\ pattern then it must be a drive designator // if we see the :\ pattern then it must be a drive designator
if( pos0 != wxString::npos ) if( aliasEnd != wxString::npos )
{ {
size_t pos1 = aFileName.find( ":\\" ); size_t pos1 = aFileName.find( ":\\" );
if( pos1 != wxString::npos && ( pos1 != pos0 || pos1 != 1 ) ) if( pos1 != wxString::npos && ( pos1 != aliasEnd || pos1 != 1 ) )
return false; return false;
// if we have a drive designator then we have no alias // if we have a drive designator then we have no alias
if( pos1 != wxString::npos ) if( pos1 != wxString::npos )
pos0 = wxString::npos; aliasEnd = wxString::npos;
} }
#else #else
filename.Replace( "\\", "/" ); filename.Replace( "\\", "/" );
#endif #endif
// names may not end with ':' // names may not end with ':'
if( pos0 == aFileName.length() -1 ) if( aliasEnd == aFileName.length() - 1 )
return false; return false;
if( pos0 != wxString::npos ) if( aliasEnd != wxString::npos )
{ {
// ensure the alias component is not empty // ensure the alias component is not empty
if( pos0 == 0 ) if( aliasEnd == aliasStart )
return false; return false;
lpath = filename.substr( 0, pos0 ); lpath = filename.substr( aliasStart, aliasEnd );
// check the alias for restricted characters // check the alias for restricted characters
if( wxString::npos != lpath.find_first_of( "{}[]()%~<>\"='`;:.,&?/\\|$" ) ) if( wxString::npos != lpath.find_first_of( "{}[]()%~<>\"='`;:.,&?/\\|$" ) )
return false; return false;
hasAlias = true; hasAlias = true;
lpath = aFileName.substr( pos0 + 1 ); lpath = aFileName.substr( aliasEnd + 1 );
} }
else else
{ {
@ -954,15 +957,15 @@ bool S3D_RESOLVER::ValidateFileName( const wxString& aFileName, bool& hasAlias )
// in the case of ${ENV_VAR}|$(ENV_VAR)/path, strip the // in the case of ${ENV_VAR}|$(ENV_VAR)/path, strip the
// environment string before testing // environment string before testing
pos0 = wxString::npos; aliasEnd = wxString::npos;
if( aFileName.StartsWith( "${" ) ) if( aFileName.StartsWith( "${" ) )
pos0 = aFileName.find( '}' ); aliasEnd = aFileName.find( '}' );
else if( aFileName.StartsWith( "$(" ) ) else if( aFileName.StartsWith( "$(" ) )
pos0 = aFileName.find( ')' ); aliasEnd = aFileName.find( ')' );
if( pos0 != wxString::npos ) if( aliasEnd != wxString::npos )
lpath = aFileName.substr( pos0 + 1 ); lpath = aFileName.substr( aliasEnd + 1 );
} }