ar: hopefully fix out-of-bounds read in get_header_ar()
[oweals/busybox.git] / archival / ar.c
index 05556c6cb5d547904bba5468bbc85aeebb58e20c..f4edeb087c2cf7aa8661d06687e58aadb4170b07 100644 (file)
  * between different systems
  * http://www.unix-systems.org/single_unix_specification_v2/xcu/ar.html
  */
+//config:config AR
+//config:      bool "ar (9.5 kb)"
+//config:      default n  # needs to be improved to be able to replace binutils ar
+//config:      help
+//config:      ar is an archival utility program used to create, modify, and
+//config:      extract contents from archives. In practice, it is used exclusively
+//config:      for object module archives used by compilers.
+//config:
+//config:      Unless you have a specific application which requires ar, you should
+//config:      probably say N here: most compilers come with their own ar utility.
+//config:
+//config:config FEATURE_AR_LONG_FILENAMES
+//config:      bool "Support long filenames (not needed for debs)"
+//config:      default y
+//config:      depends on AR
+//config:      help
+//config:      By default the ar format can only store the first 15 characters
+//config:      of the filename, this option removes that limitation.
+//config:      It supports the GNU ar long filename method which moves multiple long
+//config:      filenames into a the data section of a new ar entry.
+//config:
+//config:config FEATURE_AR_CREATE
+//config:      bool "Support archive creation"
+//config:      default y
+//config:      depends on AR
+//config:      help
+//config:      This enables archive creation (-c and -r) with busybox ar.
+
+//applet:IF_AR(APPLET(ar, BB_DIR_USR_BIN, BB_SUID_DROP))
+
+//kbuild:lib-$(CONFIG_AR) += ar.o
+
+//usage:#define ar_trivial_usage
+//usage:       "[-o] [-v] [-p] [-t] [-x] ARCHIVE FILES"
+//usage:#define ar_full_usage "\n\n"
+//usage:       "Extract or list FILES from an ar archive\n"
+//usage:     "\n       -o      Preserve original dates"
+//usage:     "\n       -p      Extract to stdout"
+//usage:     "\n       -t      List"
+//usage:     "\n       -x      Extract"
+//usage:     "\n       -v      Verbose"
 
 #include "libbb.h"
-#include "unarchive.h"
+#include "bb_archive.h"
 #include "ar.h"
 
 #if ENABLE_FEATURE_AR_CREATE
@@ -71,7 +112,7 @@ static void output_ar_header(archive_handle_t *handle)
 }
 
 /*
- * when replacing files in an existing archive, copy from the the
+ * when replacing files in an existing archive, copy from the
  * original archive those files that are to be left intact
  */
 static void FAST_FUNC copy_data(archive_handle_t *handle)
@@ -179,17 +220,17 @@ static void FAST_FUNC header_verbose_list_ar(const file_header_t *file_header)
        );
 }
 
-#define AR_OPT_VERBOSE         (1 << 0)
-#define AR_OPT_PRESERVE_DATE   (1 << 1)
+#define AR_OPT_VERBOSE          (1 << 0)
+#define AR_OPT_PRESERVE_DATE    (1 << 1)
 /* "ar r" implies create, but warns about it. c suppresses warning.
  * bbox accepts but ignores it: */
-#define AR_OPT_CREATE          (1 << 2)
+#define AR_OPT_CREATE           (1 << 2)
 
-#define AR_CMD_PRINT           (1 << 3)
-#define FIRST_CMD AR_CMD_PRINT
-#define AR_CMD_LIST            (1 << 4)
-#define AR_CMD_EXTRACT         (1 << 5)
-#define AR_CMD_INSERT          (1 << 6)
+#define AR_CMD_PRINT            (1 << 3)
+#define FIRST_CMD               AR_CMD_PRINT
+#define AR_CMD_LIST             (1 << 4)
+#define AR_CMD_EXTRACT          (1 << 5)
+#define AR_CMD_INSERT           (1 << 6)
 
 int ar_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int ar_main(int argc UNUSED_PARAM, char **argv)
@@ -199,11 +240,16 @@ int ar_main(int argc UNUSED_PARAM, char **argv)
 
        archive_handle = init_handle();
 
-       /* --: prepend '-' to the first argument if required */
-       /* -1: at least one param is reqd */
-       /* one of p,t,x[,r] is required */
-       opt_complementary = "--:-1:p:t:x"IF_FEATURE_AR_CREATE(":r");
-       opt = getopt32(argv, "voc""ptx"IF_FEATURE_AR_CREATE("r"));
+       /* prepend '-' to the first argument if required */
+       if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0')
+               argv[1] = xasprintf("-%s", argv[1]);
+       opt = getopt32(argv, "^"
+               "voc""ptx"IF_FEATURE_AR_CREATE("r")
+               "\0"
+               /* -1: at least one arg is reqd */
+               /* one of p,t,x[,r] is required */
+               "-1:p:t:x"IF_FEATURE_AR_CREATE(":r")
+       );
        argv += optind;
 
        t = opt / FIRST_CMD;