[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug in "sort -n -k1.4,1.2"
From: |
Cliff Miller |
Subject: |
bug in "sort -n -k1.4,1.2" |
Date: |
Wed, 10 Jun 2009 10:18:27 -0400 |
hi,
i have a bug to report in coreutils-7.4. the problem occurs with
empty fields under -n/-g, specifically in sub-field specifications where
end < start. according to the docs,
> If the start position in a sort field specifier falls after the end of
> the line or after the end field, the field is empty.
"after the end field" seems a little unclear; i take it to mean
"after the end [position] of the field", i.e., lima < texta. the code
does numeric comparisons by temporarily writing '\0' into the end byte
of the field and then passes the now-null-terminated strings to numcompare.
the problem is that it uses *lima instead of texta[lena] (for example,
as in compare_version()); so if lima<texta, the '\0' is never seen by
numcompare, and so acts as if the field end spec were omitted.
% pwd
/u/cliffm/opt/build/coreutils-7.4
% cat /tmp/numbug
yyy 2
xxx 3
zzz 1
% ./sort -n -k1.4,1.4 /tmp/numbug
xxx 3
yyy 2
zzz 1
% ./sort -n -k1.4,1.3 /tmp/numbug
xxx 3
yyy 2
zzz 1
% ./sort -n -k1.4,1.2 /tmp/numbug
zzz 1
yyy 2
xxx 3
this problem does not occur with other ordering types because they
either test "while(texta < lima)" or they explicitly use "lena",
which corrects for the case of lima < texta.
here is a patch. one could also change the null-insertion code
in the numeric test branch, but it seems better to correctly set
lima and limb from the start.
--------------------------- snip ---------------------------
diff -Naur tmp/old/sort.c tmp/new/sort.c
--- tmp/old/sort.c 2009-05-04 01:08:15.000000000 -0400
+++ tmp/new/sort.c 2009-06-10 10:07:29.849150000 -0400
@@ -1909,9 +1909,16 @@
char const *translate = key->translate;
bool const *ignore = key->ignore;
+ /* Fix the field end positions if they precede their start
+ positions. */
+ if (lima < texta)
+ lima = texta;
+ if (limb < textb)
+ limb = textb;
+
/* Find the lengths. */
- size_t lena = lima <= texta ? 0 : lima - texta;
- size_t lenb = limb <= textb ? 0 : limb - textb;
+ size_t lena = lima - texta;
+ size_t lenb = limb - textb;
/* Actually compare the fields. */
--------------------------- snip ---------------------------
-cliff miller
cbm ((at)) whatexit.org
- bug in "sort -n -k1.4,1.2",
Cliff Miller <=