"cut -f 2-0" now fails; before, it was equivalent to "cut -f 2-"
authorJim Meyering <jim@meyering.net>
Tue, 22 May 2007 11:56:34 +0000 (13:56 +0200)
committerJim Meyering <jim@meyering.net>
Tue, 22 May 2007 11:56:34 +0000 (13:56 +0200)
Also, diagnose the '-' in "cut -f -" as an invalid range, rather
than interpreting it as the unlimited range, "1-".
* NEWS: Mention these changes.
* src/cut.c (set_fields): Don't interpret an accumulator "value"
of 0 as an unspecified range endpoint.
Give better diagnostics.
Adjust a comment so that it is true also for 64-bit size_t.
* tests/cut/Test.pm: Add tests for the above.

ChangeLog
NEWS
src/cut.c
tests/cut/Test.pm

index b7a504b..c1fe872 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2007-05-22  Jim Meyering  <jim@meyering.net>
 
+       "cut -f 2-0" now fails; before, it was equivalent to "cut -f 2-"
+       Also, diagnose the '-' in "cut -f -" as an invalid range, rather
+       than interpreting it as the unlimited range, "1-".
+       * NEWS: Mention these changes.
+       * src/cut.c (set_fields): Don't interpret an accumulator "value"
+       of 0 as an unspecified range endpoint.
+       Give better diagnostics.
+       Adjust a comment so that it is true also for 64-bit size_t.
+       * tests/cut/Test.pm: Add tests for the above.
+
        stty: fix a harmless syntax nit
        * src/stty.c (visible): Use ";" as the statement terminator
        between two assignments, not ",".
diff --git a/NEWS b/NEWS
index 0000a2b..0326681 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,11 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 ** Bug fixes
 
+  "cut -f 2-0" now fails; before, it was equivalent to "cut -f 2-"
+
+  cut now diagnoses the '-' in "cut -f -" as an invalid range, rather
+  than interpreting it as the unlimited range, "1-".
+
   ls -x DIR would sometimes output the wrong string in place of the
   first entry.  [introduced in coreutils-6.8]
 
index 0883e72..ab14abc 100644 (file)
--- a/src/cut.c
+++ b/src/cut.c
@@ -342,6 +342,8 @@ set_fields (const char *fieldstr)
 {
   size_t initial = 1;          /* Value of first number in a range.  */
   size_t value = 0;            /* If nonzero, a number being accumulated.  */
+  bool lhs_specified = false;
+  bool rhs_specified = false;
   bool dash_found = false;     /* True if a '-' is found in this field.  */
   bool field_found = false;    /* True if at least one field spec
                                   has been processed.  */
@@ -366,13 +368,8 @@ set_fields (const char *fieldstr)
          dash_found = true;
          fieldstr++;
 
-         if (value)
-           {
-             initial = value;
-             value = 0;
-           }
-         else
-           initial = 1;
+         initial = (lhs_specified ? value : 1);
+         value = 0;
        }
       else if (*fieldstr == ',' || isblank (*fieldstr) || *fieldstr == '\0')
        {
@@ -382,9 +379,12 @@ set_fields (const char *fieldstr)
            {
              dash_found = false;
 
-             /* A range.  Possibilites: -n, m-n, n-.
+             if (!lhs_specified && !rhs_specified)
+               FATAL_ERROR (_("invalid range with no endpoint: -"));
+
+             /* A range.  Possibilities: -n, m-n, n-.
                 In any case, `initial' contains the start of the range. */
-             if (value == 0)
+             if (!rhs_specified)
                {
                  /* `n-'.  From `initial' to end of line. */
                  eol_range_start = initial;
@@ -394,7 +394,7 @@ set_fields (const char *fieldstr)
                {
                  /* `m-n' or `-n' (1-n). */
                  if (value < initial)
-                   FATAL_ERROR (_("invalid byte or field list"));
+                   FATAL_ERROR (_("invalid decreasing range"));
 
                  /* Is there already a range going to end of line? */
                  if (eol_range_start != 0)
@@ -432,7 +432,7 @@ set_fields (const char *fieldstr)
                  value = 0;
                }
            }
-         else if (value != 0)
+         else
            {
              /* A simple field number, not a range. */
              ADD_RANGE_PAIR (rp, value, value);
@@ -446,6 +446,8 @@ set_fields (const char *fieldstr)
            }
 
          fieldstr++;
+         lhs_specified = false;
+         rhs_specified = false;
        }
       else if (ISDIGIT (*fieldstr))
        {
@@ -456,10 +458,15 @@ set_fields (const char *fieldstr)
            num_start = fieldstr;
          in_digits = true;
 
+         if (dash_found)
+           rhs_specified = 1;
+         else
+           lhs_specified = 1;
+
          /* Detect overflow.  */
          if (!DECIMAL_DIGIT_ACCUMULATE (value, *fieldstr - '0', size_t))
            {
-             /* In case the user specified -c4294967296,22,
+             /* In case the user specified -c$(echo 2^64|bc),22,
                 complain only about the first number.  */
              /* Determine the length of the offending number.  */
              size_t len = strspn (num_start, "0123456789");
index b4cd4e5..109a13f 100755 (executable)
@@ -1,6 +1,6 @@
 # Test 'cut'.
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2003, 2004 Free Software
+# Copyright (C) 1996, 1997, 1998, 1999, 2003, 2004, 2007 Free Software
 # Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
@@ -113,6 +113,13 @@ my @tv = (
 ['od-overlap4', '-b1-3,2-3 --output-d=:', "abcd\n",  "abc\n",  0],
 ['od-overlap5', '-b1-3,1-4 --output-d=:', "abcde\n",  "abcd\n",        0],
 
+# None of the following invalid ranges provoked an error before coreutils-6.10.
+['inval1',     '-f 2-0',       '',             '',             1],
+['inval2',     '-f -',         '',             '',             1],
+['inval3',     '-f 4,-',       '',             '',             1],
+['inval4',     '-f 1-2,-',     '',             '',             1],
+['inval5',     '-f 1-,-',      '',             '',             1],
+['inval6',     '-f -1,-',      '',             '',             1],
 );
 
 # Don't use a pipe for failing tests.  Otherwise, sometimes they