summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2015-10-19 14:44:51 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2015-10-19 14:44:51 +0200
commit2e86a5c98d8cc716844eb0084adc5849a12cf0c7 (patch)
tree66a08bc73bc4d755e9e71028e459cc2401dabe2c
parent3d0805e9e7c45e6c0f9fb5e587d8b4a5a5f3c74c (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.c21
-rwxr-xr-xtestsuite/sort.tests36
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
" "\