bug-coreutils
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]