sort: fix key with delimiters breakage
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 19 Oct 2015 12:44:51 +0000 (14:44 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 19 Oct 2015 12:44:51 +0000 (14:44 +0200)
function                                             old     new   delta
get_key                                              509     505      -4

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

index 36f02543b7fb9fc951a899e37a37ce80d07c94d6..7fb4df5bd81a91d9cd15dc543b205c4793ffd947 100644 (file)
@@ -106,7 +106,9 @@ static struct sort_key {
 
 static char *get_key(char *str, struct sort_key *key, int flags)
 {
-       int start = 0, end = 0, len, j;
+       int start = start; /* for compiler */
+       int end;
+       int len, j;
        unsigned i;
 
        /* Special case whole string, so we don't have to make a copy */
@@ -123,12 +125,15 @@ static char *get_key(char *str, struct sort_key *key, int flags)
                        end = len;
                /* Loop through fields */
                else {
+                       unsigned char ch = 0;
+
                        end = 0;
                        for (i = 1; i < key->range[2*j] + j; i++) {
                                if (key_separator) {
                                        /* Skip body of key and separator */
-                                       while (str[end]) {
-                                               if (str[end++] == key_separator)
+                                       while ((ch = str[end]) != '\0') {
+                                                       end++;
+                                               if (ch == key_separator)
                                                        break;
                                        }
                                } else {
@@ -136,7 +141,7 @@ static char *get_key(char *str, struct sort_key *key, int flags)
                                        while (isspace(str[end]))
                                                end++;
                                        /* Skip body of key */
-                                       while (str[end]) {
+                                       while (str[end] != '\0') {
                                                if (isspace(str[end]))
                                                        break;
                                                end++;
@@ -144,11 +149,17 @@ static char *get_key(char *str, struct sort_key *key, int flags)
                                }
                        }
                        /* Remove last delim: "abc:def:" => "abc:def" */
-                       if (key_separator && j && end != 0)
+                       if (j && ch) {
+                               //if (str[end-1] != key_separator)
+                               //  bb_error_msg(_and_die("BUG! "
+                               //  "str[start:%d,end:%d]:'%.*s'",
+                               //  start, end, (int)(end-start), &str[start]);
                                end--;
+                       }
                }
                if (!j) start = end;
        }
+//bb_error_msg("start:%d,end:%d", start, end);
        /* Strip leading whitespace if necessary */
 //XXX: skip_whitespace()
        if (flags & FLAG_b)
index c4b22346421e7ccefcd6d1204a233bfd36906be1..39c7af7389553347a518fb235eff0a6b270a5337 100755 (executable)
@@ -106,6 +106,42 @@ a/a:a
 a:b
 " ""
 
+testing "glibc build sort" "sort -t. -k 1,1 -k 2n,2n -k 3 input" "\
+GLIBC_2.1
+GLIBC_2.1.1
+GLIBC_2.2
+GLIBC_2.2.1
+GLIBC_2.10
+GLIBC_2.20
+GLIBC_2.21
+" "\
+GLIBC_2.21
+GLIBC_2.1.1
+GLIBC_2.2.1
+GLIBC_2.2
+GLIBC_2.20
+GLIBC_2.10
+GLIBC_2.1
+" ""
+
+testing "glibc build sort unique" "sort -u -t. -k 1,1 -k 2n,2n -k 3 input" "\
+GLIBC_2.1
+GLIBC_2.1.1
+GLIBC_2.2
+GLIBC_2.2.1
+GLIBC_2.10
+GLIBC_2.20
+GLIBC_2.21
+" "\
+GLIBC_2.10
+GLIBC_2.2.1
+GLIBC_2.1.1
+GLIBC_2.20
+GLIBC_2.2
+GLIBC_2.1
+GLIBC_2.21
+" ""
+
 testing "sort -u should consider field only when discarding" "sort -u -k2 input" "\
 a c
 " "\