sort: fix potentially buggy use of OPT_STR
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 22 Feb 2018 10:03:23 +0000 (11:03 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 22 Feb 2018 10:03:23 +0000 (11:03 +0100)
This also makes OPT_STR reused:

   text    data     bss     dec     hex filename
 930979     481    6852  938312   e5148 busybox_old
 930954     481    6852  938287   e512f busybox_unstripped
 ^^^^^^

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
coreutils/sort.c

index c24b62681697d1c5595fe97a14f85b95ba30a590..b39297a26560813927f15c8e0e0ce72fe542f049 100644 (file)
 
 #include "libbb.h"
 
-/* This is a NOEXEC applet. Be very careful! */
-
-
-/*
-       sort [-m][-o output][-bdfinru][-t char][-k keydef]... [file...]
-       sort -c [-bdfinru][-t char][-k keydef][file]
-*/
-
 /* These are sort types */
-#define OPT_STR "ngMucszbrdfimS:T:o:k:*t:"
 enum {
        FLAG_n  = 1,            /* Numeric sort */
        FLAG_g  = 2,            /* Sort using strtod() */
@@ -120,6 +111,15 @@ enum {
        FLAG_no_tie_break = 0x40000000,
 };
 
+static const char sort_opt_str[] ALIGN1 = "^"
+                       "ngMucszbrdfimS:T:o:k:*t:"
+                       "\0" "o--o:t--t"/*-t, -o: at most one of each*/;
+/*
+ * OPT_STR must not be string literal, needs to have stable address:
+ * code uses "strchr(OPT_STR,c) - OPT_STR" idiom.
+ */
+#define OPT_STR (sort_opt_str + 1)
+
 #if ENABLE_FEATURE_SORT_BIG
 static char key_separator;
 
@@ -129,6 +129,10 @@ static struct sort_key {
        unsigned flags;
 } *key_list;
 
+
+/* This is a NOEXEC applet. Be very careful! */
+
+
 static char *get_key(char *str, struct sort_key *key, int flags)
 {
        int start = start; /* for compiler */
@@ -404,9 +408,8 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
        xfunc_error_retval = 2;
 
        /* Parse command line options */
-       opts = getopt32(argv, "^"
-                       OPT_STR
-                       "\0" "o--o:t--t"/*-t, -o: at most one of each*/,
+       opts = getopt32(argv,
+                       sort_opt_str,
                        &str_ignored, &str_ignored, &str_o, &lst_k, &str_t
        );
        /* global b strips leading and trailing spaces */