[coreutils/f16] various multibyte patch fixes

Kamil Dudka kdudka at fedoraproject.org
Mon Jan 30 12:04:08 UTC 2012


commit d399388c03b4f2cfc45d7c8a78c816664ea7af78
Author: Kamil Dudka <kdudka at redhat.com>
Date:   Mon Jan 30 12:27:04 2012 +0100

    various multibyte patch fixes
    
    - fix cut output-delimiter option
    - prevent infinite loop in sort when ignoring chars
    - prevent using unitialized variable in cut
    - fix pr -c and pr -v segfault with multibyte locales
    - fix stack smashing, buffer overflow and invalid output of pr (#772172)

 coreutils-i18n.patch |  401 +++++++++++++++++++++++++++++++-------------------
 coreutils.spec       |    6 +
 2 files changed, 253 insertions(+), 154 deletions(-)
---
diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch
index 6e10f37..9c4cdf1 100644
--- a/coreutils-i18n.patch
+++ b/coreutils-i18n.patch
@@ -1,6 +1,36 @@
-diff -urNp coreutils-8.10-orig/lib/linebuffer.h coreutils-8.10/lib/linebuffer.h
---- coreutils-8.10-orig/lib/linebuffer.h	2011-01-06 09:47:56.000000000 +0100
-+++ coreutils-8.10/lib/linebuffer.h	2011-02-04 20:13:23.985464731 +0100
+From 1a1c255481be80d9a559b4783126ebbf48faa9cc Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka at redhat.com>
+Date: Mon, 30 Jan 2012 12:46:37 +0100
+Subject: [PATCH] coreutils-i18n.patch (Fedora 16)
+
+---
+ lib/linebuffer.h         |    8 +
+ src/cut.c                |  437 ++++++++++++++++++++++++++--
+ src/expand.c             |  160 ++++++++++-
+ src/fold.c               |  308 ++++++++++++++++++--
+ src/join.c               |  346 +++++++++++++++++++---
+ src/pr.c                 |  438 +++++++++++++++++++++++++---
+ src/sort.c               |  723 +++++++++++++++++++++++++++++++++++++++++++---
+ src/unexpand.c           |  226 ++++++++++++++-
+ src/uniq.c               |  258 ++++++++++++++++-
+ tests/Makefile.am        |    5 +
+ tests/misc/cut           |    4 +-
+ tests/misc/mb1.I         |    4 +
+ tests/misc/mb1.X         |    4 +
+ tests/misc/mb2.I         |    4 +
+ tests/misc/mb2.X         |    4 +
+ tests/misc/sort-mb-tests |   58 ++++
+ 16 files changed, 2804 insertions(+), 183 deletions(-)
+ create mode 100644 tests/misc/mb1.I
+ create mode 100644 tests/misc/mb1.X
+ create mode 100644 tests/misc/mb2.I
+ create mode 100644 tests/misc/mb2.X
+ create mode 100644 tests/misc/sort-mb-tests
+
+diff --git a/lib/linebuffer.h b/lib/linebuffer.h
+index 4050fb0..5eafab4 100644
+--- a/lib/linebuffer.h
++++ b/lib/linebuffer.h
 @@ -21,6 +21,11 @@
  
  # include <stdio.h>
@@ -23,9 +53,10 @@ diff -urNp coreutils-8.10-orig/lib/linebuffer.h coreutils-8.10/lib/linebuffer.h
  };
  
  /* Initialize linebuffer LINEBUFFER for use. */
-diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
---- coreutils-8.10-orig/src/cut.c	2011-01-31 13:40:38.000000000 +0100
-+++ coreutils-8.10/src/cut.c	2011-02-04 20:13:23.988464025 +0100
+diff --git a/src/cut.c b/src/cut.c
+index e2fe851..097f48a 100644
+--- a/src/cut.c
++++ b/src/cut.c
 @@ -28,6 +28,11 @@
  #include <assert.h>
  #include <getopt.h>
@@ -75,7 +106,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
 +  while (0)
 +
 +/* Get wide character on BUFPOS. BUFPOS is not included after that.
-+   If byte sequence is not valid as a character, CONVFAIL is 1. Otherwise 0. */ 
++   If byte sequence is not valid as a character, CONVFAIL is 1. Otherwise 0. */
 +#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \
 +  do                                                                        \
 +    {                                                                        \
@@ -170,7 +201,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
  
  /* True if the --output-delimiter=STRING option was specified.  */
  static bool output_delimiter_specified;
-@@ -207,7 +284,7 @@ Mandatory arguments to long options are 
+@@ -207,7 +284,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
    -f, --fields=LIST       select only these fields;  also print any line\n\
                              that contains no delimiter character, unless\n\
                              the -s option is specified\n\
@@ -226,7 +257,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
      }
  
    max_range_endpoint = 0;
-@@ -580,6 +662,63 @@ cut_bytes (FILE *stream)
+@@ -582,6 +664,77 @@ cut_bytes (FILE *stream)
      }
  }
  
@@ -234,11 +265,11 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
 +/* This function is in use for the following case.
 +
 +   1. Read from the stream STREAM, printing to standard output any selected
-+   characters. 
++   characters.
 +
 +   2. Read from stream STREAM, printing to standard output any selected bytes,
 +   without splitting multibyte characters.  */
-+ 
++
 +static void
 +cut_characters_or_cut_bytes_no_split (FILE *stream)
 +{
@@ -251,6 +282,9 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
 +                           as same character as WC. */
 +  mbstate_t state;        /* State of the stream. */
 +  int convfail = 0;                /* 1, when conversion is failed. Otherwise 0. */
++  /* Whether to begin printing delimiters between ranges for the current line.
++     Set after we've begun printing data corresponding to the first range.  */
++  bool print_delimiter = false;
 +
 +  idx = 0;
 +  buflen = 0;
@@ -273,12 +307,23 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
 +        {
 +          putchar ('\n');
 +          idx = 0;
++          print_delimiter = false;
 +        }
 +      else
 +        {
++          bool range_start;
++          bool *rs = output_delimiter_specified ? &range_start : NULL;
 +          idx += (operating_mode == byte_mode) ? mblength : 1;
-+          if (print_kth (idx, NULL))
-+            fwrite (bufpos, mblength, sizeof(char), stdout);
++          if (print_kth (idx, rs))
++            {
++              if (rs && *rs && print_delimiter)
++                {
++                  fwrite (output_delimiter_string, sizeof (char),
++                         output_delimiter_length, stdout);
++               }
++              print_delimiter = true;
++              fwrite (bufpos, mblength, sizeof(char), stdout);
++            }
 +        }
 +
 +      buflen -= mblength;
@@ -286,11 +331,11 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
 +    }
 +}
 +#endif
-+                   
++
  /* Read from stream STREAM, printing to standard output any selected fields.  */
  
  static void
-@@ -702,13 +841,192 @@ cut_fields (FILE *stream)
+@@ -704,13 +857,195 @@ cut_fields (FILE *stream)
      }
  }
  
@@ -310,7 +355,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
 +  size_t mblength;        /* The byte size of a multibyte character which shows
 +                           as same character as WC. */
 +  mbstate_t state;        /* State of the stream. */
-+  int convfail;                /* 1, when conversion is failed. Otherwise 0. */
++  int convfail = 0;                /* 1, when conversion is failed. Otherwise 0. */
 +
 +  found_any_selected_field = 0;
 +  field_idx = 1;
@@ -321,7 +366,10 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
 +  c = getc (stream);
 +  empty_input = (c == EOF);
 +  if (c != EOF)
++  {
 +    ungetc (c, stream);
++    wc = 0;
++  }
 +  else
 +    wc = WEOF;
 +
@@ -486,7 +534,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
  }
  
  /* Process file FILE to standard output.
-@@ -760,6 +1078,8 @@ main (int argc, char **argv)
+@@ -762,6 +1097,8 @@ main (int argc, char **argv)
    bool ok;
    bool delim_specified = false;
    char *spec_list_string IF_LINT ( = NULL);
@@ -495,7 +543,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
  
    initialize_main (&argc, &argv);
    set_program_name (argv[0]);
-@@ -782,7 +1102,6 @@ main (int argc, char **argv)
+@@ -784,7 +1121,6 @@ main (int argc, char **argv)
        switch (optc)
          {
          case 'b':
@@ -503,7 +551,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
            /* Build the byte list. */
            if (operating_mode != undefined_mode)
              FATAL_ERROR (_("only one type of list may be specified"));
-@@ -790,6 +1109,14 @@ main (int argc, char **argv)
+@@ -792,6 +1128,14 @@ main (int argc, char **argv)
            spec_list_string = optarg;
            break;
  
@@ -518,7 +566,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
          case 'f':
            /* Build the field list. */
            if (operating_mode != undefined_mode)
-@@ -801,10 +1128,35 @@ main (int argc, char **argv)
+@@ -803,10 +1147,35 @@ main (int argc, char **argv)
          case 'd':
            /* New delimiter. */
            /* Interpret -d '' to mean `use the NUL byte as the delimiter.'  */
@@ -558,7 +606,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
            break;
  
          case OUTPUT_DELIMITER_OPTION:
-@@ -817,6 +1169,7 @@ main (int argc, char **argv)
+@@ -819,6 +1188,7 @@ main (int argc, char **argv)
            break;
  
          case 'n':
@@ -566,7 +614,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
            break;
  
          case 's':
-@@ -839,7 +1192,7 @@ main (int argc, char **argv)
+@@ -841,7 +1211,7 @@ main (int argc, char **argv)
    if (operating_mode == undefined_mode)
      FATAL_ERROR (_("you must specify a list of bytes, characters, or fields"));
  
@@ -575,7 +623,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
      FATAL_ERROR (_("an input delimiter may be specified only\
   when operating on fields"));
  
-@@ -866,15 +1219,34 @@ main (int argc, char **argv)
+@@ -868,15 +1238,34 @@ main (int argc, char **argv)
      }
  
    if (!delim_specified)
@@ -607,7 +655,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
 +      if (MB_CUR_MAX <= 1 || force_singlebyte_mode)
 +#endif
 +        {
-+          static char dummy[2]; 
++          static char dummy[2];
 +          dummy[0] = delim;
 +          dummy[1] = '\0';
 +          output_delimiter_string = dummy;
@@ -616,9 +664,10 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c
      }
  
    if (optind == argc)
-diff -urNp coreutils-8.10-orig/src/expand.c coreutils-8.10/src/expand.c
---- coreutils-8.10-orig/src/expand.c	2011-01-31 13:40:38.000000000 +0100
-+++ coreutils-8.10/src/expand.c	2011-02-04 20:13:23.990463571 +0100
+diff --git a/src/expand.c b/src/expand.c
+index a562290..543554a 100644
+--- a/src/expand.c
++++ b/src/expand.c
 @@ -38,12 +38,29 @@
  #include <stdio.h>
  #include <getopt.h>
@@ -806,9 +855,10 @@ diff -urNp coreutils-8.10-orig/src/expand.c coreutils-8.10/src/expand.c
  
    if (have_read_stdin && fclose (stdin) != 0)
      error (EXIT_FAILURE, errno, "-");
-diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c
---- coreutils-8.10-orig/src/fold.c	2011-01-31 13:40:38.000000000 +0100
-+++ coreutils-8.10/src/fold.c	2011-02-04 20:13:23.992463115 +0100
+diff --git a/src/fold.c b/src/fold.c
+index 7880e3c..41466dd 100644
+--- a/src/fold.c
++++ b/src/fold.c
 @@ -22,12 +22,34 @@
  #include <getopt.h>
  #include <sys/types.h>
@@ -890,7 +940,7 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c
    {"spaces", no_argument, NULL, 's'},
    {"width", required_argument, NULL, 'w'},
    {GETOPT_HELP_OPTION_DECL},
-@@ -78,6 +121,7 @@ Mandatory arguments to long options are 
+@@ -78,6 +121,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
  "), stdout);
        fputs (_("\
    -b, --bytes         count bytes rather than columns\n\
@@ -898,7 +948,7 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c
    -s, --spaces        break at spaces\n\
    -w, --width=WIDTH   use WIDTH columns instead of 80\n\
  "), stdout);
-@@ -95,7 +139,7 @@ Mandatory arguments to long options are 
+@@ -95,7 +139,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
  static size_t
  adjust_column (size_t column, char c)
  {
@@ -940,7 +990,7 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c
  
    fadvise (istream, FADVISE_SEQUENTIAL);
  
-@@ -171,6 +199,15 @@ fold_file (char const *filename, size_t 
+@@ -171,6 +199,15 @@ fold_file (char const *filename, size_t width)
                bool found_blank = false;
                size_t logical_end = offset_out;
  
@@ -956,16 +1006,16 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c
                /* Look for the last blank. */
                while (logical_end)
                  {
-@@ -217,11 +254,221 @@ fold_file (char const *filename, size_t 
+@@ -217,11 +254,221 @@ fold_file (char const *filename, size_t width)
        line_out[offset_out++] = c;
      }
  
 -  saved_errno = errno;
 +  *saved_errno = errno;
- 
-   if (offset_out)
-     fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
- 
++
++  if (offset_out)
++    fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
++
 +}
 +
 +#if HAVE_MBRTOWC
@@ -1067,7 +1117,7 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c
 +                  fwrite (line_out, sizeof(char), offset_out, stdout);
 +                  START_NEW_LINE;
 +                  continue;
-+                  
++
 +                case L'\b':
 +                  increment = (column > 0) ? -1 : 0;
 +                  break;
@@ -1137,10 +1187,10 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c
 +    }
 +
 +  *saved_errno = errno;
-+
-+  if (offset_out)
-+    fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
-+
+ 
+   if (offset_out)
+     fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
+ 
 +}
 +#endif
 +
@@ -1179,7 +1229,7 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c
    if (ferror (istream))
      {
        error (0, saved_errno, "%s", filename);
-@@ -254,7 +502,8 @@ main (int argc, char **argv)
+@@ -254,7 +501,8 @@ main (int argc, char **argv)
  
    atexit (close_stdout);
  
@@ -1189,7 +1239,7 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c
  
    while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
      {
-@@ -263,7 +512,15 @@ main (int argc, char **argv)
+@@ -263,7 +511,15 @@ main (int argc, char **argv)
        switch (optc)
          {
          case 'b':		/* Count bytes rather than columns. */
@@ -1206,9 +1256,10 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c
            break;
  
          case 's':		/* Break at word boundaries. */
-diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c
---- coreutils-8.10-orig/src/join.c	2011-01-31 13:40:38.000000000 +0100
-+++ coreutils-8.10/src/join.c	2011-02-04 20:20:15.985114387 +0100
+diff --git a/src/join.c b/src/join.c
+index 941185c..c458f58 100644
+--- a/src/join.c
++++ b/src/join.c
 @@ -22,18 +22,32 @@
  #include <sys/types.h>
  #include <getopt.h>
@@ -1423,11 +1474,11 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c
 +  extract_field (line, ptr, lim - ptr);
 +}
 +#endif
-+ 
++
  static void
  freeline (struct line *line)
  {
-@@ -308,56 +467,115 @@ keycmp (struct line const *line1, struct
+@@ -308,56 +467,115 @@ keycmp (struct line const *line1, struct line const *line2,
          size_t jf_1, size_t jf_2)
  {
    /* Start of field to compare in each file.  */
@@ -1551,7 +1602,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c
 -        return xmemcoll (beg1, len1, beg2, len2);
 -      diff = memcmp (beg1, beg2, MIN (len1, len2));
 +      copy[0] = (unsigned char *) beg[0];
-+      copy[1] = (unsigned char *) beg[1];  
++      copy[1] = (unsigned char *) beg[1];
      }
  
 +  if (hard_LC_COLLATE)
@@ -1566,7 +1617,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c
  }
  
  /* Check that successive input lines PREV and CURRENT from input file
-@@ -438,6 +656,11 @@ get_line (FILE *fp, struct line **linep,
+@@ -438,6 +656,11 @@ get_line (FILE *fp, struct line **linep, int which)
        return false;
      }
  
@@ -1578,7 +1629,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c
    xfields (line);
  
    if (prevline[which - 1])
-@@ -537,21 +760,28 @@ prfield (size_t n, struct line const *li
+@@ -537,21 +760,28 @@ prfield (size_t n, struct line const *line)
  
  /* Output all the fields in line, other than the join field.  */
  
@@ -1618,7 +1669,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c
    size_t field;
    struct line const *line;
  
-@@ -596,7 +825,7 @@ prjoin (struct line const *line1, struct
+@@ -596,7 +825,7 @@ prjoin (struct line const *line1, struct line const *line2)
            o = o->next;
            if (o == NULL)
              break;
@@ -1632,7 +1683,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c
          case 't':
            {
 -            unsigned char newtab = optarg[0];
-+            char *newtab;
++            char *newtab = NULL;
 +            size_t newtablen;
 +            newtab = xstrdup (optarg);
 +#if HAVE_MBRTOWC
@@ -1653,8 +1704,9 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c
 +#endif
 +              newtablen = 1;
              if (! newtab)
+-              newtab = '\n'; /* '' => process the whole line.  */
 +            {
-               newtab = '\n'; /* '' => process the whole line.  */
++              newtab = "\n"; /* '' => process the whole line.  */
 +            }
              else if (optarg[1])
                {
@@ -1683,9 +1735,10 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c
            break;
  
          case NOCHECK_ORDER_OPTION:
-diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
---- coreutils-8.10-orig/src/pr.c	2011-01-31 13:40:38.000000000 +0100
-+++ coreutils-8.10/src/pr.c	2011-02-04 20:13:24.002460897 +0100
+diff --git a/src/pr.c b/src/pr.c
+index 7e6b13c..19db10e 100644
+--- a/src/pr.c
++++ b/src/pr.c
 @@ -312,6 +312,32 @@
  
  #include <getopt.h>
@@ -1963,7 +2016,19 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
    if (*arg)
      {
        long int tmp_long;
-@@ -1249,7 +1375,7 @@ init_parameters (int number_of_files)
+@@ -1212,6 +1338,11 @@ static void
+ init_parameters (int number_of_files)
+ {
+   int chars_used_by_number = 0;
++  int mb_len = 1;
++#if HAVE_MBRTOWC
++  if (MB_CUR_MAX > 1)
++    mb_len = MB_LEN_MAX;
++#endif
+ 
+   lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
+   if (lines_per_body <= 0)
+@@ -1249,7 +1380,7 @@ init_parameters (int number_of_files)
            else
              col_sep_string = column_separator;
  
@@ -1972,7 +2037,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
            use_col_separator = true;
          }
        /* It's rather pointless to define a TAB separator with column
-@@ -1280,11 +1406,11 @@ init_parameters (int number_of_files)
+@@ -1280,11 +1411,11 @@ init_parameters (int number_of_files)
               TAB_WIDTH (chars_per_input_tab, chars_per_number);   */
  
        /* Estimate chars_per_text without any margin and keep it constant. */
@@ -1986,7 +2051,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
  
        /* The number is part of the column width unless we are
           printing files in parallel. */
-@@ -1299,7 +1425,7 @@ init_parameters (int number_of_files)
+@@ -1299,7 +1430,7 @@ init_parameters (int number_of_files)
      }
  
    chars_per_column = (chars_per_line - chars_used_by_number -
@@ -1995,7 +2060,16 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
  
    if (chars_per_column < 1)
      error (EXIT_FAILURE, 0, _("page width too narrow"));
-@@ -1424,7 +1550,7 @@ init_funcs (void)
+@@ -1316,7 +1447,7 @@ init_parameters (int number_of_files)
+      We've to use 8 as the lower limit, if we use chars_per_default_tab = 8
+      to expand a tab which is not an input_tab-char. */
+   free (clump_buff);
+-  clump_buff = xmalloc (MAX (8, chars_per_input_tab));
++  clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab));
+ }
+ 
+ /* Open the necessary files,
+@@ -1424,7 +1555,7 @@ init_funcs (void)
  
    /* Enlarge p->start_position of first column to use the same form of
       padding_not_printed with all columns. */
@@ -2004,7 +2078,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
  
    /* This loop takes care of all but the rightmost column. */
  
-@@ -1458,7 +1584,7 @@ init_funcs (void)
+@@ -1458,7 +1589,7 @@ init_funcs (void)
          }
        else
          {
@@ -2013,7 +2087,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
            h_next = h + chars_per_column;
          }
      }
-@@ -1749,9 +1875,9 @@ static void
+@@ -1749,9 +1880,9 @@ static void
  align_column (COLUMN *p)
  {
    padding_not_printed = p->start_position;
@@ -2025,7 +2099,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
        padding_not_printed = ANYWHERE;
      }
  
-@@ -2022,13 +2148,13 @@ store_char (char c)
+@@ -2022,13 +2153,13 @@ store_char (char c)
        /* May be too generous. */
        buff = X2REALLOC (buff, &buff_allocated);
      }
@@ -2041,7 +2115,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
    char *s;
    int left_cut;
  
-@@ -2051,22 +2177,24 @@ add_line_number (COLUMN *p)
+@@ -2051,22 +2182,24 @@ add_line_number (COLUMN *p)
        /* Tabification is assumed for multiple columns, also for n-separators,
           but `default n-separator = TAB' hasn't been given priority over
           equal column_width also specified by POSIX. */
@@ -2070,7 +2144,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
          output_position = POS_AFTER_TAB (chars_per_output_tab,
                            output_position);
      }
-@@ -2227,7 +2355,7 @@ print_white_space (void)
+@@ -2227,7 +2360,7 @@ print_white_space (void)
    while (goal - h_old > 1
           && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal)
      {
@@ -2079,7 +2153,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
        h_old = h_new;
      }
    while (++h_old <= goal)
-@@ -2247,6 +2375,7 @@ print_sep_string (void)
+@@ -2247,6 +2380,7 @@ print_sep_string (void)
  {
    char *s;
    int l = col_sep_length;
@@ -2087,7 +2161,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
  
    s = col_sep_string;
  
-@@ -2260,6 +2389,7 @@ print_sep_string (void)
+@@ -2260,6 +2394,7 @@ print_sep_string (void)
      {
        for (; separators_not_printed > 0; --separators_not_printed)
          {
@@ -2095,7 +2169,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
            while (l-- > 0)
              {
                /* 3 types of sep_strings: spaces only, spaces and chars,
-@@ -2273,12 +2403,15 @@ print_sep_string (void)
+@@ -2273,12 +2408,15 @@ print_sep_string (void)
                  }
                else
                  {
@@ -2112,7 +2186,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
            /* sep_string ends with some spaces */
            if (spaces_not_printed > 0)
              print_white_space ();
-@@ -2306,7 +2439,7 @@ print_clump (COLUMN *p, int n, char *clu
+@@ -2306,7 +2444,7 @@ print_clump (COLUMN *p, int n, char *clump)
     required number of tabs and spaces. */
  
  static void
@@ -2121,7 +2195,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
  {
    if (tabify_output)
      {
-@@ -2330,6 +2463,74 @@ print_char (char c)
+@@ -2330,6 +2468,74 @@ print_char (char c)
    putchar (c);
  }
  
@@ -2196,7 +2270,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
  /* Skip to page PAGE before printing.
     PAGE may be larger than total number of pages. */
  
-@@ -2509,9 +2710,9 @@ read_line (COLUMN *p)
+@@ -2509,9 +2715,9 @@ read_line (COLUMN *p)
            align_empty_cols = false;
          }
  
@@ -2208,7 +2282,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
            padding_not_printed = ANYWHERE;
          }
  
-@@ -2612,9 +2813,9 @@ print_stored (COLUMN *p)
+@@ -2612,9 +2818,9 @@ print_stored (COLUMN *p)
          }
      }
  
@@ -2220,7 +2294,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
        padding_not_printed = ANYWHERE;
      }
  
-@@ -2627,8 +2828,8 @@ print_stored (COLUMN *p)
+@@ -2627,8 +2833,8 @@ print_stored (COLUMN *p)
    if (spaces_not_printed == 0)
      {
        output_position = p->start_position + end_vector[line];
@@ -2231,7 +2305,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
      }
  
    return true;
-@@ -2647,7 +2848,7 @@ print_stored (COLUMN *p)
+@@ -2647,7 +2853,7 @@ print_stored (COLUMN *p)
     number of characters is 1.) */
  
  static int
@@ -2240,7 +2314,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
  {
    unsigned char uc = c;
    char *s = clump_buff;
-@@ -2657,10 +2858,10 @@ char_to_clump (char c)
+@@ -2657,10 +2863,10 @@ char_to_clump (char c)
    int chars;
    int chars_per_c = 8;
  
@@ -2253,7 +2327,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
      {
        width = TAB_WIDTH (chars_per_c, input_position);
  
-@@ -2741,6 +2942,154 @@ char_to_clump (char c)
+@@ -2741,6 +2947,154 @@ char_to_clump (char c)
    return chars;
  }
  
@@ -2298,7 +2372,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
 +              width = +4;
 +              chars = +4;
 +              *s++ = '\\';
-+              sprintf (esc_buff, "%03o", mbc[0]);
++              sprintf (esc_buff, "%03o", (unsigned char) mbc[0]);
 +              for (i = 0; i <= 2; ++i)
 +                *s++ = (int) esc_buff[i];
 +            }
@@ -2347,7 +2421,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
 +                      width += 4;
 +                      chars += 4;
 +                      *s++ = '\\';
-+                      sprintf (esc_buff, "%03o", c);
++                      sprintf (esc_buff, "%03o", (unsigned char) mbc[i]);
 +                      for (j = 0; j <= 2; ++j)
 +                        *s++ = (int) esc_buff[j];
 +                    }
@@ -2368,7 +2442,7 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
 +                          width += 4;
 +                          chars += 4;
 +                          *s++ = '\\';
-+                          sprintf (esc_buff, "%03o", c);
++                          sprintf (esc_buff, "%03o", (unsigned char) mbc[i]);
 +                          for (j = 0; j <= 2; ++j)
 +                            *s++ = (int) esc_buff[j];
 +                        }
@@ -2408,9 +2482,10 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c
  /* We've just printed some files and need to clean up things before
     looking for more options and printing the next batch of files.
  
-diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
---- coreutils-8.10-orig/src/sort.c	2011-02-03 11:24:35.000000000 +0100
-+++ coreutils-8.10/src/sort.c	2011-02-04 20:15:44.160384535 +0100
+diff --git a/src/sort.c b/src/sort.c
+index 07d6765..fa3c0a9 100644
+--- a/src/sort.c
++++ b/src/sort.c
 @@ -22,11 +22,20 @@
  
  #include <config.h>
@@ -2432,7 +2507,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  #include "system.h"
  #include "argmatch.h"
  #include "error.h"
-@@ -163,12 +172,34 @@ static int thousands_sep;
+@@ -167,12 +176,34 @@ static int thousands_sep;
  
  /* Nonzero if the corresponding locales are hard.  */
  static bool hard_LC_COLLATE;
@@ -2468,7 +2543,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  /* The kind of blanks for '-b' to skip in various options. */
  enum blanktype { bl_start, bl_end, bl_both };
  
-@@ -335,13 +366,11 @@ static bool reverse;
+@@ -343,13 +374,11 @@ static bool reverse;
     they were read if all keys compare equal.  */
  static bool stable;
  
@@ -2485,7 +2560,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  
  /* Flag to remove consecutive duplicate lines from the output.
     Only the last of a sequence of equal lines will be output. */
-@@ -775,6 +804,46 @@ reap_all (void)
+@@ -783,6 +812,46 @@ reap_all (void)
      reap (-1);
  }
  
@@ -2532,7 +2607,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  /* Clean up any remaining temporary files.  */
  
  static void
-@@ -1207,7 +1276,7 @@ zaptemp (char const *name)
+@@ -1215,7 +1284,7 @@ zaptemp (char const *name)
    free (node);
  }
  
@@ -2541,7 +2616,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  
  static int
  struct_month_cmp (void const *m1, void const *m2)
-@@ -1222,7 +1291,7 @@ struct_month_cmp (void const *m1, void c
+@@ -1230,7 +1299,7 @@ struct_month_cmp (void const *m1, void const *m2)
  /* Initialize the character class tables. */
  
  static void
@@ -2550,7 +2625,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  {
    size_t i;
  
-@@ -1234,7 +1303,7 @@ inittables (void)
+@@ -1242,7 +1311,7 @@ inittables (void)
        fold_toupper[i] = toupper (i);
      }
  
@@ -2559,7 +2634,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
    /* If we're not in the "C" locale, read different names for months.  */
    if (hard_LC_TIME)
      {
-@@ -1316,6 +1385,84 @@ specify_nmerge (int oi, char c, char con
+@@ -1324,6 +1393,84 @@ specify_nmerge (int oi, char c, char const *s)
      xstrtol_fatal (e, oi, c, long_options, s);
  }
  
@@ -2644,7 +2719,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  /* Specify the amount of main memory to use when sorting.  */
  static void
  specify_sort_size (int oi, char c, char const *s)
-@@ -1544,7 +1691,7 @@ buffer_linelim (struct buffer const *buf
+@@ -1552,7 +1699,7 @@ buffer_linelim (struct buffer const *buf)
     by KEY in LINE. */
  
  static char *
@@ -2653,7 +2728,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  {
    char *ptr = line->text, *lim = ptr + line->length - 1;
    size_t sword = key->sword;
-@@ -1553,10 +1700,10 @@ begfield (struct line const *line, struc
+@@ -1561,10 +1708,10 @@ begfield (struct line const *line, struct keyfield const *key)
    /* The leading field separator itself is included in a field when -t
       is absent.  */
  
@@ -2666,7 +2741,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
            ++ptr;
          if (ptr < lim)
            ++ptr;
-@@ -1582,11 +1729,70 @@ begfield (struct line const *line, struc
+@@ -1590,11 +1737,70 @@ begfield (struct line const *line, struct keyfield const *key)
    return ptr;
  }
  
@@ -2738,7 +2813,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  {
    char *ptr = line->text, *lim = ptr + line->length - 1;
    size_t eword = key->eword, echar = key->echar;
-@@ -1601,10 +1807,10 @@ limfield (struct line const *line, struc
+@@ -1609,10 +1815,10 @@ limfield (struct line const *line, struct keyfield const *key)
       `beginning' is the first character following the delimiting TAB.
       Otherwise, leave PTR pointing at the first `blank' character after
       the preceding field.  */
@@ -2751,7 +2826,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
            ++ptr;
          if (ptr < lim && (eword || echar))
            ++ptr;
-@@ -1650,10 +1856,10 @@ limfield (struct line const *line, struc
+@@ -1658,10 +1864,10 @@ limfield (struct line const *line, struct keyfield const *key)
       */
  
    /* Make LIM point to the end of (one byte past) the current field.  */
@@ -2764,7 +2839,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
        if (newlim)
          lim = newlim;
      }
-@@ -1684,6 +1890,130 @@ limfield (struct line const *line, struc
+@@ -1692,6 +1898,130 @@ limfield (struct line const *line, struct keyfield const *key)
    return ptr;
  }
  
@@ -2895,7 +2970,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  /* Fill BUF reading from FP, moving buf->left bytes from the end
     of buf->buf to the beginning first.  If EOF is reached and the
     file wasn't terminated by a newline, supply one.  Set up BUF's line
-@@ -1770,8 +2100,22 @@ fillbuf (struct buffer *buf, FILE *fp, c
+@@ -1778,8 +2108,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file)
                    else
                      {
                        if (key->skipsblanks)
@@ -2920,7 +2995,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
                        line->keybeg = line_start;
                      }
                  }
-@@ -1892,7 +2236,7 @@ human_numcompare (char const *a, char co
+@@ -1900,7 +2244,7 @@ human_numcompare (char const *a, char const *b)
     hideously fast. */
  
  static int
@@ -2929,7 +3004,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  {
    while (blanks[to_uchar (*a)])
      a++;
-@@ -1902,6 +2246,25 @@ numcompare (char const *a, char const *b
+@@ -1910,6 +2254,25 @@ numcompare (char const *a, char const *b)
    return strnumcmp (a, b, decimal_point, thousands_sep);
  }
  
@@ -2955,7 +3030,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  static int
  general_numcompare (char const *sa, char const *sb)
  {
-@@ -1934,7 +2297,7 @@ general_numcompare (char const *sa, char
+@@ -1942,7 +2305,7 @@ general_numcompare (char const *sa, char const *sb)
     Return 0 if the name in S is not recognized.  */
  
  static int
@@ -2964,7 +3039,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  {
    size_t lo = 0;
    size_t hi = MONTHS_PER_YEAR;
-@@ -2209,15 +2572,14 @@ debug_key (struct line const *line, stru
+@@ -2217,15 +2580,14 @@ debug_key (struct line const *line, struct keyfield const *key)
            char saved = *lim;
            *lim = '\0';
  
@@ -2982,7 +3057,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
            else if (key->general_numeric)
              ignore_value (strtold (beg, &tighter_lim));
            else if (key->numeric || key->human_numeric)
-@@ -2361,7 +2723,7 @@ key_warnings (struct keyfield const *gke
+@@ -2369,7 +2731,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
        bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key)
                                   && !(key->schar || key->echar);
        bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y  */
@@ -2991,7 +3066,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
            && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned))
                || (!key->skipsblanks && key->schar)
                || (!key->skipeblanks && key->echar)))
-@@ -2419,11 +2781,83 @@ key_warnings (struct keyfield const *gke
+@@ -2427,11 +2789,83 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
      error (0, 0, _("option `-r' only applies to last-resort comparison"));
  }
  
@@ -3076,7 +3151,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  {
    struct keyfield *key = keylist;
  
-@@ -2508,7 +2942,7 @@ keycompare (struct line const *a, struct
+@@ -2516,7 +2950,7 @@ keycompare (struct line const *a, struct line const *b)
            else if (key->human_numeric)
              diff = human_numcompare (ta, tb);
            else if (key->month)
@@ -3085,7 +3160,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
            else if (key->random)
              diff = compare_random (ta, tlena, tb, tlenb);
            else if (key->version)
-@@ -2624,6 +3058,179 @@ keycompare (struct line const *a, struct
+@@ -2632,6 +3066,180 @@ keycompare (struct line const *a, struct line const *b)
    return key->reverse ? -diff : diff;
  }
  
@@ -3167,7 +3242,8 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
 +              if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1)        \
 +                STATE = state_bak;                                        \
 +              if (!ignore)                                                \
-+                COPY[NEW_LEN++] = TEXT[i++];                                \
++                COPY[NEW_LEN++] = TEXT[i];                                \
++              i++;                                                         \
 +              continue;                                                        \
 +            }                                                                \
 +                                                                        \
@@ -3265,7 +3341,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
  /* Compare two lines A and B, returning negative, zero, or positive
     depending on whether A compares less than, equal to, or greater than B. */
  
-@@ -4087,7 +4694,7 @@ main (int argc, char **argv)
+@@ -4095,7 +4703,7 @@ main (int argc, char **argv)
    initialize_exit_failure (SORT_FAILURE);
  
    hard_LC_COLLATE = hard_locale (LC_COLLATE);
@@ -3274,7 +3350,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
    hard_LC_TIME = hard_locale (LC_TIME);
  #endif
  
-@@ -4108,6 +4715,29 @@ main (int argc, char **argv)
+@@ -4116,6 +4724,29 @@ main (int argc, char **argv)
        thousands_sep = -1;
    }
  
@@ -3304,7 +3380,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
    have_read_stdin = false;
    inittables ();
  
-@@ -4378,13 +5008,34 @@ main (int argc, char **argv)
+@@ -4386,13 +5017,34 @@ main (int argc, char **argv)
  
          case 't':
            {
@@ -3343,7 +3419,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
                  else
                    {
                      /* Provoke with `sort -txx'.  Complain about
-@@ -4395,9 +5046,12 @@ main (int argc, char **argv)
+@@ -4403,9 +5055,12 @@ main (int argc, char **argv)
                             quote (optarg));
                    }
                }
@@ -3358,9 +3434,10 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c
            }
            break;
  
-diff -urNp coreutils-8.10-orig/src/unexpand.c coreutils-8.10/src/unexpand.c
---- coreutils-8.10-orig/src/unexpand.c	2011-01-31 13:40:38.000000000 +0100
-+++ coreutils-8.10/src/unexpand.c	2011-02-04 20:13:24.015458014 +0100
+diff --git a/src/unexpand.c b/src/unexpand.c
+index 0014375..a10b7d4 100644
+--- a/src/unexpand.c
++++ b/src/unexpand.c
 @@ -39,12 +39,29 @@
  #include <stdio.h>
  #include <getopt.h>
@@ -3614,9 +3691,10 @@ diff -urNp coreutils-8.10-orig/src/unexpand.c coreutils-8.10/src/unexpand.c
  
    if (have_read_stdin && fclose (stdin) != 0)
      error (EXIT_FAILURE, errno, "-");
-diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
---- coreutils-8.10-orig/src/uniq.c	2011-01-31 13:40:38.000000000 +0100
-+++ coreutils-8.10/src/uniq.c	2011-02-04 20:13:24.018457349 +0100
+diff --git a/src/uniq.c b/src/uniq.c
+index b35938a..8e952c4 100644
+--- a/src/uniq.c
++++ b/src/uniq.c
 @@ -21,6 +21,16 @@
  #include <getopt.h>
  #include <sys/types.h>
@@ -3655,7 +3733,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
  
  /* The official name of this program (e.g., no `g' prefix).  */
  #define PROGRAM_NAME "uniq"
-@@ -108,6 +130,10 @@ static enum delimit_method const delimit
+@@ -108,6 +130,10 @@ static enum delimit_method const delimit_method_map[] =
  /* Select whether/how to delimit groups of duplicate lines.  */
  static enum delimit_method delimit_groups;
  
@@ -3666,16 +3744,16 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
  static struct option const longopts[] =
  {
    {"count", no_argument, NULL, 'c'},
-@@ -207,7 +233,7 @@ size_opt (char const *opt, char const *m
+@@ -207,7 +233,7 @@ size_opt (char const *opt, char const *msgid)
     return a pointer to the beginning of the line's field to be compared. */
  
  static char *
 -find_field (struct linebuffer const *line)
-+find_field_uni (struct linebuffer *line)
++find_field_uni (struct linebuffer const *line)
  {
    size_t count;
    char const *lp = line->buffer;
-@@ -227,6 +253,83 @@ find_field (struct linebuffer const *lin
+@@ -227,6 +253,83 @@ find_field (struct linebuffer const *line)
    return line->buffer + i;
  }
  
@@ -3725,7 +3803,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
 +      while (pos < size)
 +        {
 +          MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail);
-+ 
++
 +          if (convfail || !iswblank (wc))
 +            {
 +              pos += mblength;
@@ -3759,7 +3837,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
  /* Return false if two strings OLD and NEW match, true if not.
     OLD and NEW point not to the beginnings of the lines
     but rather to the beginnings of the fields to compare.
-@@ -235,6 +338,8 @@ find_field (struct linebuffer const *lin
+@@ -235,6 +338,8 @@ find_field (struct linebuffer const *line)
  static bool
  different (char *old, char *new, size_t oldlen, size_t newlen)
  {
@@ -3768,7 +3846,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
    if (check_chars < oldlen)
      oldlen = check_chars;
    if (check_chars < newlen)
-@@ -242,14 +347,92 @@ different (char *old, char *new, size_t 
+@@ -242,14 +347,92 @@ different (char *old, char *new, size_t oldlen, size_t newlen)
  
    if (ignore_case)
      {
@@ -3866,7 +3944,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
  
  /* Output the line in linebuffer LINE to standard output
     provided that the switches say it should be output.
-@@ -305,15 +488,43 @@ check_file (const char *infile, const ch
+@@ -305,15 +488,43 @@ check_file (const char *infile, const char *outfile, char delimiter)
      {
        char *prevfield IF_LINT ( = NULL);
        size_t prevlen IF_LINT ( = 0);
@@ -3910,7 +3988,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
            if (prevline->length == 0
                || different (thisfield, prevfield, thislen, prevlen))
              {
-@@ -332,17 +543,26 @@ check_file (const char *infile, const ch
+@@ -332,17 +543,26 @@ check_file (const char *infile, const char *outfile, char delimiter)
        size_t prevlen;
        uintmax_t match_count = 0;
        bool first_delimiter = true;
@@ -3937,7 +4015,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
            if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
              {
                if (ferror (stdin))
-@@ -351,6 +571,14 @@ check_file (const char *infile, const ch
+@@ -351,6 +571,14 @@ check_file (const char *infile, const char *outfile, char delimiter)
              }
            thisfield = find_field (thisline);
            thislen = thisline->length - 1 - (thisfield - thisline->buffer);
@@ -3952,7 +4030,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
            match = !different (thisfield, prevfield, thislen, prevlen);
            match_count += match;
  
-@@ -383,6 +612,9 @@ check_file (const char *infile, const ch
+@@ -383,6 +611,9 @@ check_file (const char *infile, const char *outfile, char delimiter)
                SWAP_LINES (prevline, thisline);
                prevfield = thisfield;
                prevlen = thislen;
@@ -3962,7 +4040,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
                if (!match)
                  match_count = 0;
              }
-@@ -428,6 +660,19 @@ main (int argc, char **argv)
+@@ -428,6 +659,19 @@ main (int argc, char **argv)
  
    atexit (close_stdout);
  
@@ -3982,10 +4060,11 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c
    skip_chars = 0;
    skip_fields = 0;
    check_chars = SIZE_MAX;
-diff -urNp coreutils-8.10-orig/tests/Makefile.am coreutils-8.10/tests/Makefile.am
---- coreutils-8.10-orig/tests/Makefile.am	2011-02-04 20:12:58.236173903 +0100
-+++ coreutils-8.10/tests/Makefile.am	2011-02-04 20:13:24.020456905 +0100
-@@ -235,6 +235,7 @@ TESTS =						\
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 20188a3..2de855c 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -236,6 +236,7 @@ TESTS =						\
    misc/sort-debug-keys				\
    misc/sort-debug-warn				\
    misc/sort-files0-from				\
@@ -3993,7 +4072,7 @@ diff -urNp coreutils-8.10-orig/tests/Makefile.am coreutils-8.10/tests/Makefile.a
    misc/sort-float				\
    misc/sort-merge				\
    misc/sort-merge-fdlimit			\
-@@ -505,6 +506,10 @@ TESTS =						\
+@@ -511,6 +512,10 @@ TESTS =						\
    $(root_tests)
  
  pr_data =					\
@@ -4004,9 +4083,10 @@ diff -urNp coreutils-8.10-orig/tests/Makefile.am coreutils-8.10/tests/Makefile.a
    pr/0F						\
    pr/0FF					\
    pr/0FFnt					\
-diff -urNp coreutils-8.10-orig/tests/misc/cut coreutils-8.10/tests/misc/cut
---- coreutils-8.10-orig/tests/misc/cut	2011-01-31 13:40:38.000000000 +0100
-+++ coreutils-8.10/tests/misc/cut	2011-02-04 20:13:24.021456684 +0100
+diff --git a/tests/misc/cut b/tests/misc/cut
+index c905ba9..5a76d85 100755
+--- a/tests/misc/cut
++++ b/tests/misc/cut
 @@ -26,7 +26,7 @@ use strict;
  my $prog = 'cut';
  my $try = "Try \`$prog --help' for more information.\n";
@@ -4025,41 +4105,51 @@ diff -urNp coreutils-8.10-orig/tests/misc/cut coreutils-8.10/tests/misc/cut
    ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
    ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
    ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1},
-diff -urNp coreutils-8.10-orig/tests/misc/mb1.I coreutils-8.10/tests/misc/mb1.I
---- coreutils-8.10-orig/tests/misc/mb1.I	1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.10/tests/misc/mb1.I	2011-02-04 20:13:24.022456462 +0100
+diff --git a/tests/misc/mb1.I b/tests/misc/mb1.I
+new file mode 100644
+index 0000000..90a0d9a
+--- /dev/null
++++ b/tests/misc/mb1.I
 @@ -0,0 +1,4 @@
 +Apple@10
 +Banana@5
 +Citrus@20
 +Cherry@30
-diff -urNp coreutils-8.10-orig/tests/misc/mb1.X coreutils-8.10/tests/misc/mb1.X
---- coreutils-8.10-orig/tests/misc/mb1.X	1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.10/tests/misc/mb1.X	2011-02-04 20:13:24.023456240 +0100
+diff --git a/tests/misc/mb1.X b/tests/misc/mb1.X
+new file mode 100644
+index 0000000..310655e
+--- /dev/null
++++ b/tests/misc/mb1.X
 @@ -0,0 +1,4 @@
 +Banana@5
 +Apple@10
 +Citrus@20
 +Cherry@30
-diff -urNp coreutils-8.10-orig/tests/misc/mb2.I coreutils-8.10/tests/misc/mb2.I
---- coreutils-8.10-orig/tests/misc/mb2.I	1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.10/tests/misc/mb2.I	2011-02-04 20:13:24.024456019 +0100
+diff --git a/tests/misc/mb2.I b/tests/misc/mb2.I
+new file mode 100644
+index 0000000..cbb392a
+--- /dev/null
++++ b/tests/misc/mb2.I
 @@ -0,0 +1,4 @@
 +Apple@AA10@@20
 +Banana@AA5@@30
 +Citrus@AA20@@5
 +Cherry@AA30@@10
-diff -urNp coreutils-8.10-orig/tests/misc/mb2.X coreutils-8.10/tests/misc/mb2.X
---- coreutils-8.10-orig/tests/misc/mb2.X	1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.10/tests/misc/mb2.X	2011-02-04 20:13:24.024456019 +0100
+diff --git a/tests/misc/mb2.X b/tests/misc/mb2.X
+new file mode 100644
+index 0000000..5f0fc66
+--- /dev/null
++++ b/tests/misc/mb2.X
 @@ -0,0 +1,4 @@
 +Citrus@AA20@@5
 +Cherry@AA30@@10
 +Apple@AA10@@20
 +Banana@AA5@@30
-diff -urNp coreutils-8.10-orig/tests/misc/sort-mb-tests coreutils-8.10/tests/misc/sort-mb-tests
---- coreutils-8.10-orig/tests/misc/sort-mb-tests	1970-01-01 01:00:00.000000000 +0100
-+++ coreutils-8.10/tests/misc/sort-mb-tests	2011-02-04 20:13:24.025455797 +0100
+diff --git a/tests/misc/sort-mb-tests b/tests/misc/sort-mb-tests
+new file mode 100644
+index 0000000..bdef0cd
+--- /dev/null
++++ b/tests/misc/sort-mb-tests
 @@ -0,0 +1,58 @@
 +#! /bin/sh
 +case $# in
@@ -4079,7 +4169,7 @@ diff -urNp coreutils-8.10-orig/tests/misc/sort-mb-tests coreutils-8.10/tests/mis
 +$xx -t @ -k2 -n misc/mb1.I > misc/mb1.O
 +code=$?
 +if test $code != 0; then
-+  $echo "Test mb1 failed: $xx return code $code differs from expected value 0" 1>&2
++  $echo "Test mb1 failed: $xx return code $code differs from expected value 0"
 +  errors=`expr $errors + 1`
 +else
 +  cmp misc/mb1.O $srcdir/misc/mb1.X > /dev/null 2>&1
@@ -4119,3 +4209,6 @@ diff -urNp coreutils-8.10-orig/tests/misc/sort-mb-tests coreutils-8.10/tests/mis
 +fi
 +test $errors = 0 || errors=1
 +exit $errors
+-- 
+1.7.1
+
diff --git a/coreutils.spec b/coreutils.spec
index 81707d3..5125ebb 100644
--- a/coreutils.spec
+++ b/coreutils.spec
@@ -338,6 +338,12 @@ fi
 - do not use shebang in sourced colorls.csh
 - su: fix shell suspend in tcsh (#597928)
 - variable "u" should be static in uname processor type patch
+- various multibyte patch fixes:
+  - fix cut output-delimiter option
+  - prevent infinite loop in sort when ignoring chars
+  - prevent using unitialized variable in cut
+  - fix pr -c and pr -v segfault with multibyte locales
+  - fix stack smashing, buffer overflow and invalid output of pr (#772172)
 
 * Sun Jan 29 2012 Kamil Dudka <kdudka at redhat.com> - 8.12-5
 - output the correct ownership in chown -v (upstream bug #10636)


More information about the scm-commits mailing list