]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/ar.c
gdb/riscv: Handle empty C++ structs during argument passing
[thirdparty/binutils-gdb.git] / binutils / ar.c
index 69f20f95c0f8ecc3cdb7cb61efb1fbbb24ad92b3..a65dd62fdf22453ff0a0120b5b41380fdcdcc55b 100644 (file)
@@ -1,5 +1,5 @@
 /* ar.c - Archive modify and extract.
-   Copyright (C) 1991-2014 Free Software Foundation, Inc.
+   Copyright (C) 1991-2019 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
 #include "progress.h"
 #include "getopt.h"
 #include "aout/ar.h"
-#include "libbfd.h"
 #include "bucomm.h"
 #include "arsup.h"
 #include "filenames.h"
 #include "binemul.h"
+#include "plugin-api.h"
 #include "plugin.h"
 
 #ifdef __GO32___
@@ -75,6 +75,9 @@ int silent_create = 0;
 /* Nonzero means describe each action performed.  */
 int verbose = 0;
 
+/* Nonzero means display offsets of files in the archive.  */
+int display_offsets = 0;
+
 /* Nonzero means preserve dates of members when extracting them.  */
 int preserve_dates = 0;
 
@@ -138,7 +141,11 @@ static int show_version = 0;
 
 static int show_help = 0;
 
+#if BFD_SUPPORTS_PLUGINS
+static const char *plugin_target = "plugin";
+#else
 static const char *plugin_target = NULL;
+#endif
 
 static const char *target = NULL;
 
@@ -264,13 +271,13 @@ usage (int help)
 #if BFD_SUPPORTS_PLUGINS
   /* xgettext:c-format */
   const char *command_line
-    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV]"
+    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV]"
        " [--plugin <name>] [member-name] [count] archive-file file...\n");
 
 #else
   /* xgettext:c-format */
   const char *command_line
-    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV]"
+    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV]"
        " [member-name] [count] archive-file file...\n");
 #endif
   s = help ? stdout : stderr;
@@ -286,7 +293,7 @@ usage (int help)
   fprintf (s, _("  q[f]         - quick append file(s) to the archive\n"));
   fprintf (s, _("  r[ab][f][u]  - replace existing or insert new file(s) into the archive\n"));
   fprintf (s, _("  s            - act as ranlib\n"));
-  fprintf (s, _("  t            - display contents of archive\n"));
+  fprintf (s, _("  t[O][v]      - display contents of the archive\n"));
   fprintf (s, _("  x[o]         - extract file(s) from the archive\n"));
   fprintf (s, _(" command specific modifiers:\n"));
   fprintf (s, _("  [a]          - put file(s) after [member-name]\n"));
@@ -309,6 +316,7 @@ usage (int help)
   fprintf (s, _("  [f]          - truncate inserted file names\n"));
   fprintf (s, _("  [P]          - use full path names when matching\n"));
   fprintf (s, _("  [o]          - preserve original dates\n"));
+  fprintf (s, _("  [O]          - display offsets of files in the archive\n"));
   fprintf (s, _("  [u]          - only replace files that are newer than current archive contents\n"));
   fprintf (s, _(" generic modifiers:\n"));
   fprintf (s, _("  [c]          - do not warn if the library had to be created\n"));
@@ -469,7 +477,7 @@ decode_options (int argc, char **argv)
       argv = new_argv;
     }
 
-  while ((c = getopt_long (argc, argv, "hdmpqrtxlcoVsSuvabiMNfPTDU",
+  while ((c = getopt_long (argc, argv, "hdmpqrtxlcoOVsSuvabiMNfPTDU",
                           long_options, NULL)) != EOF)
     {
       switch (c)
@@ -524,6 +532,9 @@ decode_options (int argc, char **argv)
         case 'o':
           preserve_dates = 1;
           break;
+        case 'O':
+          display_offsets = 1;
+          break;
         case 'V':
           show_version = TRUE;
           break;
@@ -571,7 +582,6 @@ decode_options (int argc, char **argv)
           break;
        case OPTION_PLUGIN:
 #if BFD_SUPPORTS_PLUGINS
-         plugin_target = "plugin";
          bfd_plugin_set_plugin (optarg);
 #else
          fprintf (stderr, _("sorry - this program has been built without plugin support\n"));
@@ -632,7 +642,6 @@ ranlib_main (int argc, char **argv)
          /* PR binutils/13493: Support plugins.  */
        case OPTION_PLUGIN:
 #if BFD_SUPPORTS_PLUGINS
-         plugin_target = "plugin";
          bfd_plugin_set_plugin (optarg);
 #else
          fprintf (stderr, _("sorry - this program has been built without plugin support\n"));
@@ -689,6 +698,7 @@ main (int argc, char **argv)
 
   program_name = argv[0];
   xmalloc_set_program_name (program_name);
+  bfd_set_error_program_name (program_name);
 #if BFD_SUPPORTS_PLUGINS
   bfd_plugin_set_program_name (program_name);
 #endif
@@ -708,7 +718,8 @@ main (int argc, char **argv)
 
   START_PROGRESS (program_name, 0);
 
-  bfd_init ();
+  if (bfd_init () != BFD_INIT_MAGIC)
+    fatal (_("fatal error: libbfd ABI mismatch"));
   set_default_bfd_target ();
 
   xatexit (remove_output);
@@ -744,6 +755,12 @@ main (int argc, char **argv)
     {
       bfd *arch;
 
+      /* Fail if no files are specified on the command line.
+        (But not for MRI mode which allows for reading arguments
+        and filenames from stdin).  */
+      if (argv[arg_index] == NULL)
+       usage (0);
+
       /* We don't use do_quick_append any more.  Too many systems
         expect ar to always rebuild the symbol table even when q is
         used.  */
@@ -773,18 +790,26 @@ main (int argc, char **argv)
       default_deterministic ();
 
       if (postype != pos_default)
-       posname = argv[arg_index++];
+       {
+         posname = argv[arg_index++];
+         if (posname == NULL)
+           fatal (_("missing position arg."));
+       }
 
       if (counted_name_mode)
        {
          if (operation != extract && operation != del)
            fatal (_("`N' is only meaningful with the `x' and `d' options."));
+         if (argv[arg_index] == NULL)
+           fatal (_("`N' missing value."));
          counted_name_counter = atoi (argv[arg_index++]);
          if (counted_name_counter <= 0)
            fatal (_("Value for `N' must be positive."));
        }
 
       inarch_filename = argv[arg_index++];
+      if (inarch_filename == NULL)
+       usage (0);
 
       for (file_count = 0; argv[arg_index + file_count] != NULL; file_count++)
        continue;
@@ -952,7 +977,7 @@ open_inarch (const char *archive_filename, const char *file)
                 bfd_get_filename (arch));
          goto bloser;
        }
-    }  
+    }
 
   last_one = &(arch->archive_next);
   /* Read all the contents right away, regardless.  */
@@ -1000,7 +1025,7 @@ print_contents (bfd *abfd)
       if (nread != tocopy)
        /* xgettext:c-format */
        fatal (_("%s is not a valid archive"),
-              bfd_get_filename (bfd_my_archive (abfd)));
+              bfd_get_filename (abfd->my_archive));
 
       /* fwrite in mingw32 may return int instead of bfd_size_type. Cast the
         return value to bfd_size_type to avoid comparison between signed and
@@ -1032,6 +1057,16 @@ extract_file (bfd *abfd)
   bfd_size_type size;
   struct stat buf;
 
+  /* PR binutils/17533: Do not allow directory traversal
+     outside of the current directory tree.  */
+  if (! is_valid_archive_path (bfd_get_filename (abfd)))
+    {
+      non_fatal (_("illegal pathname found in archive member: %s"),
+                bfd_get_filename (abfd));
+      free (cbuf);
+      return;
+    }
+
   if (bfd_stat_arch_elt (abfd, &buf) != 0)
     /* xgettext:c-format */
     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
@@ -1068,7 +1103,7 @@ extract_file (bfd *abfd)
        if (nread != tocopy)
          /* xgettext:c-format */
          fatal (_("%s is not a valid archive"),
-                bfd_get_filename (bfd_my_archive (abfd)));
+                bfd_get_filename (abfd->my_archive));
 
        /* See comment above; this saves disk arm motion */
        if (ostream == NULL)
@@ -1170,6 +1205,7 @@ write_archive (bfd *iarch)
   if (smart_rename (new_name, old_name, 0) != 0)
     xexit (1);
   free (old_name);
+  free (new_name);
 }
 
 /* Return a pointer to the pointer to the entry which should be rplacd'd
@@ -1475,5 +1511,5 @@ ranlib_touch (const char *archname)
 static void
 print_descr (bfd *abfd)
 {
-  print_arelt_descr (stdout, abfd, verbose);
+  print_arelt_descr (stdout, abfd, verbose, display_offsets);
 }