diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2015-10-19 14:44:51 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2015-10-19 14:44:51 +0200 |
commit | 2e86a5c98d8cc716844eb0084adc5849a12cf0c7 (patch) | |
tree | 66a08bc73bc4d755e9e71028e459cc2401dabe2c | |
parent | 3d0805e9e7c45e6c0f9fb5e587d8b4a5a5f3c74c (diff) |
sort: fix key with delimiters breakage
function old new delta
get_key 509 505 -4
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | coreutils/sort.c | 21 | ||||
-rwxr-xr-x | testsuite/sort.tests | 36 |
2 files changed, 52 insertions, 5 deletions
diff --git a/coreutils/sort.c b/coreutils/sort.c index 36f02543b..7fb4df5bd 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c @@ -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) diff --git a/testsuite/sort.tests b/testsuite/sort.tests index c4b223464..39c7af738 100755 --- a/testsuite/sort.tests +++ b/testsuite/sort.tests @@ -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 " "\ |