daily update
[binutils-gdb.git] / bfd / archive.c
index 4b6a81cb0f998443098ed77036f09cfdf32eb9df..dc39751aac1cc584ad3733ee0c2a5a5f35858097 100644 (file)
@@ -379,6 +379,13 @@ _bfd_find_nested_archive (bfd *arch_bfd, const char *filename)
   bfd *abfd;
   const char *target;
 
+  /* PR 15140: Don't allow a nested archive pointing to itself.  */
+  if (filename_cmp (filename, arch_bfd->filename) == 0)
+    {
+      bfd_set_error (bfd_error_malformed_archive);
+      return NULL;
+    }
+
   for (abfd = arch_bfd->nested_archives;
        abfd != NULL;
        abfd = abfd->archive_next)
@@ -617,7 +624,6 @@ _bfd_append_relative_path (bfd *arch, char *elt_name)
 bfd *
 _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
 {
-  static file_ptr prev_filepos;
   struct areltdata *new_areldata;
   bfd *n_nfd;
   char *filename;
@@ -625,12 +631,6 @@ _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
   n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos);
   if (n_nfd)
     return n_nfd;
-  /* PR15140: Prevent an inifnite recursion scanning a malformed nested archive.  */
-  if (filepos == prev_filepos)
-    {
-      bfd_set_error (bfd_error_malformed_archive);
-      return NULL;
-    }
 
   if (0 > bfd_seek (archive, filepos, SEEK_SET))
     return NULL;
@@ -639,7 +639,6 @@ _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
     return NULL;
 
   filename = new_areldata->filename;
-  prev_filepos = filepos;
 
   if (bfd_is_thin_archive (archive))
     {
@@ -706,7 +705,7 @@ _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
   else
     {
       n_nfd->origin = n_nfd->proxy_origin;
-      n_nfd->filename = filename;
+      n_nfd->filename = xstrdup (filename);
     }
 
   n_nfd->arelt_data = new_areldata;
@@ -2733,7 +2732,7 @@ _bfd_archive_close_and_cleanup (bfd *abfd)
          bfd_ardata (abfd)->cache = NULL;
        }
     }
-  else if (arch_eltdata (abfd) != NULL)
+  if (arch_eltdata (abfd) != NULL)
     {
       struct areltdata *ared = arch_eltdata (abfd);
       htab_t htab = (htab_t) ared->parent_cache;