]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
sort: with -h, disallow thousands separator between number and unit
authorKamil Dudka <kdudka@redhat.com>
Mon, 18 Jul 2016 17:04:45 +0000 (19:04 +0200)
committerPádraig Brady <P@draigBrady.com>
Mon, 18 Jul 2016 21:24:26 +0000 (22:24 +0100)
* src/sort.c (traverse_raw_number): Accept thousands separator only
if it is immediately followed by a digit.
* tests/misc/sort-h-thousands-sep.sh: Cover the fix for this bug.

Suggested by Pádraig Brady in http://bugs.gnu.org/24015

src/sort.c
tests/misc/sort-h-thousands-sep.sh

index 038f6aee3270b8a0718926667deb7dd266e18f68..079547595af3977fc0292678ee2dd87e3db93487 100644 (file)
@@ -1895,6 +1895,7 @@ traverse_raw_number (char const **number)
   char const *p = *number;
   unsigned char ch;
   unsigned char max_digit = '\0';
+  bool ends_with_thousands_sep = false;
 
   /* Scan to end of number.
      Decimals or separators not followed by digits stop the scan.
@@ -1910,10 +1911,18 @@ traverse_raw_number (char const **number)
       /* Allow to skip only one occurrence of thousands_sep to avoid finding
          the unit in the next column in case thousands_sep matches as blank
          and is used as column delimiter.  */
-      if (*p == thousands_sep)
+      ends_with_thousands_sep = (*p == thousands_sep);
+      if (ends_with_thousands_sep)
         ++p;
     }
 
+  if (ends_with_thousands_sep)
+    {
+      /* thousands_sep not followed by digit is not allowed.  */
+      *number = p - 2;
+      return max_digit;
+    }
+
   if (ch == decimal_point)
     while (ISDIGIT (ch = *p++))
       if (max_digit < ch)
index 17f1b6c9872dc0c7b655de74551201afaaae35b0..3ffa89eeb24ad4f0e8589cf24f1eb3bce7c419d6 100755 (executable)
 
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ sort
+
 test "$(LC_ALL=sv_SE locale thousands_sep)" = ' ' \
   || skip_ 'The Swedish locale with blank thousands separator is unavailable.'
 
-tee exp1 > in << _EOF_
-1       1k      4 003   1M
-2k      2M      4 002   2
-3M      3       4 001   3k
+tee exp1 exp3 > in << _EOF_
+1       1k      1 M     4 003   1M
+2k      2M      2 k     4 002   2
+3M      3       3 G     4 001   3k
 _EOF_
 
 cat > exp2 << _EOF_
-3M      3       4 001   3k
-1       1k      4 003   1M
-2k      2M      4 002   2
+3M      3       3 G     4 001   3k
+1       1k      1 M     4 003   1M
+2k      2M      2 k     4 002   2
 _EOF_
 
-cat > exp3 << _EOF_
-3M      3       4 001   3k
-2k      2M      4 002   2
-1       1k      4 003   1M
+cat > exp5 << _EOF_
+3M      3       3 G     4 001   3k
+2k      2M      2 k     4 002   2
+1       1k      1 M     4 003   1M
 _EOF_
 
-for i in 1 2 3; do
+for i in 1 2 3 5; do
   LC_ALL="sv_SE.utf8" sort -h -k $i "in" > "out${i}" || fail=1
   compare "exp${i}" "out${i}" || fail=1
 done