@ -386,10 +386,11 @@ byte_get_64 (unsigned char *field, elf_vma *high, elf_vma *low)
char *
adjust_relative_path ( const char * file_name , const char * name ,
int name_len )
uns ig ned long name_len )
{
char * member_file_name ;
const char * base_name = lbasename ( file_name ) ;
size_t amt ;
/* This is a proxy entry for a thin archive member.
If the extended name table contains an absolute path
@ -399,7 +400,10 @@ adjust_relative_path (const char *file_name, const char *name,
archive is located . */
if ( IS_ABSOLUTE_PATH ( name ) | | base_name = = file_name )
{
member_file_name = ( char * ) malloc ( name_len + 1 ) ;
amt = name_len + 1 ;
if ( amt = = 0 )
return NULL ;
member_file_name = ( char * ) malloc ( amt ) ;
if ( member_file_name = = NULL )
{
error ( _ ( " Out of memory \n " ) ) ;
@ -413,7 +417,18 @@ adjust_relative_path (const char *file_name, const char *name,
/* Concatenate the path components of the archive file name
to the relative path name from the extended name table . */
size_t prefix_len = base_name - file_name ;
member_file_name = ( char * ) malloc ( prefix_len + name_len + 1 ) ;
amt = prefix_len + name_len + 1 ;
/* PR 17531: file: 2896dc8b
Catch wraparound . */
if ( amt < prefix_len | | amt < name_len )
{
error ( _ ( " Abnormal length of thin archive member name: %lx \n " ) ,
name_len ) ;
return NULL ;
}
member_file_name = ( char * ) malloc ( amt ) ;
if ( member_file_name = = NULL )
{
error ( _ ( " Out of memory \n " ) ) ;
@ -445,6 +460,14 @@ process_archive_index_and_symbols (struct archive_info * arch,
unsigned long size ;
size = strtoul ( arch - > arhdr . ar_size , NULL , 10 ) ;
/* PR 17531: file: 912bd7de. */
if ( ( signed long ) size < 0 )
{
error ( _ ( " %s: invalid archive header size: %ld \n " ) ,
arch - > file_name , size ) ;
return FALSE ;
}
size = size + ( size & 1 ) ;
arch - > next_arhdr_offset + = sizeof arch - > arhdr + size ;
@ -623,9 +646,17 @@ setup_archive (struct archive_info *arch, const char *file_name,
{
/* This is the archive string table holding long member names. */
arch - > longnames_size = strtoul ( arch - > arhdr . ar_size , NULL , 10 ) ;
/* PR 17531: file: 01068045. */
if ( arch - > longnames_size < 8 )
{
error ( _ ( " %s: long name table is too small, (size = %ld) \n " ) ,
file_name , arch - > longnames_size ) ;
return 1 ;
}
arch - > next_arhdr_offset + = sizeof arch - > arhdr + arch - > longnames_size ;
arch - > longnames = ( char * ) malloc ( arch - > longnames_size ) ;
/* Plus one to allow for a string terminator. */
arch - > longnames = ( char * ) malloc ( arch - > longnames_size + 1 ) ;
if ( arch - > longnames = = NULL )
{
error ( _ ( " Out of memory reading long symbol names in archive \n " ) ) ;
@ -719,17 +750,31 @@ get_archive_member_name (struct archive_info *arch,
if ( arch - > is_thin_archive & & endp ! = NULL & & * endp = = ' : ' )
arch - > nested_member_origin = strtoul ( endp + 1 , NULL , 10 ) ;
if ( j > arch - > longnames_size )
{
error ( _ ( " Found long name index (%ld) beyond end of long name table \n " ) , j ) ;
return NULL ;
}
while ( ( j < arch - > longnames_size )
& & ( arch - > longnames [ j ] ! = ' \n ' )
& & ( arch - > longnames [ j ] ! = ' \0 ' ) )
j + + ;
if ( arch - > longnames [ j - 1 ] = = ' / ' )
if ( j > 0 & & arch - > longnames [ j - 1 ] = = ' / ' )
j - - ;
if ( j > arch - > longnames_size )
j = arch - > longnames_size ;
arch - > longnames [ j ] = ' \0 ' ;
if ( ! arch - > is_thin_archive | | arch - > nested_member_origin = = 0 )
return arch - > longnames + k ;
/* PR 17531: file: 2896dc8b. */
if ( k > = j )
{
error ( _ ( " Invalid Thin archive member name \n " ) ) ;
return NULL ;
}
/* This is a proxy for a member of a nested archive.
Find the name of the member in that archive . */
member_file_name = adjust_relative_path ( arch - > file_name ,