This can be triggered by using month sort
The issue with the original code is that after the call to mbsrtowcs() and wcsrtombs() returns, the source pointer will be set to NULL causing the later free() call has no effect at all --- The issue also exists in c6 branch
SOURCES/coreutils-i18n.patch | 45 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 23 deletions(-)
diff --git a/SOURCES/coreutils-i18n.patch b/SOURCES/coreutils-i18n.patch index a3c7b33..cdcaffd 100644 --- a/SOURCES/coreutils-i18n.patch +++ b/SOURCES/coreutils-i18n.patch @@ -2963,7 +2963,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c line->keybeg = line_start; } } -@@ -1945,7 +2291,7 @@ human_numcompare (char const *a, char co +@@ -1943,7 +2289,7 @@ human_numcompare (char *a, char *b) hideously fast. */
static int @@ -2972,7 +2972,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1955,6 +2301,25 @@ numcompare (char const *a, char const *b +@@ -1953,6 +2299,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); }
@@ -2998,7 +2998,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* Work around a problem whereby the long double value returned by glibc's strtold ("NaN", ...) contains uninitialized bits: clear all bytes of A and B before calling strtold. FIXME: remove this function once -@@ -2005,7 +2370,7 @@ general_numcompare (char const *sa, char +@@ -2003,7 +2368,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */
static int @@ -3007,7 +3007,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, stru +@@ -2278,15 +2643,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0';
@@ -3025,7 +3025,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gke +@@ -2430,7 +2794,7 @@ key_warnings (struct keyfield const *gke 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 */ @@ -3034,7 +3034,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gke +@@ -2488,11 +2852,86 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option '-r' only applies to last-resort comparison")); }
@@ -3047,8 +3047,8 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c + register int lo = 0, hi = MONTHS_PER_YEAR, result; + char *tmp; + size_t wclength, mblength; -+ const char **pp; -+ const wchar_t **wpp; ++ const char *pp; ++ const wchar_t *wpp; + wchar_t *month_wcs; + mbstate_t state; + @@ -3066,12 +3066,12 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c + tmp = (char *) xmalloc (len + 1); + memcpy (tmp, s, len); + tmp[len] = '\0'; -+ pp = (const char **)&tmp; + month_wcs = (wchar_t *) xmalloc ((len + 1) * sizeof (wchar_t)); + memset (&state, '\0', sizeof(mbstate_t)); + -+ wclength = mbsrtowcs (month_wcs, pp, len + 1, &state); -+ if (wclength == (size_t)-1 || *pp != NULL) ++ pp = tmp; ++ wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state); ++ if (wclength == (size_t)-1 || pp != NULL) + error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s)); + + for (i = 0; i < wclength; i++) @@ -3084,10 +3084,9 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c + } + } + -+ wpp = (const wchar_t **)&month_wcs; -+ -+ mblength = wcsrtombs (month, wpp, len + 1, &state); -+ assert (mblength != (-1) && *wpp == NULL); ++ wpp = month_wcs; ++ mblength = wcsrtombs (month, &wpp, len + 1, &state); ++ assert (mblength != (-1) && wpp == NULL); + + do + { @@ -3123,7 +3122,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { struct keyfield *key = keylist;
-@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct +@@ -2577,7 +3016,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3132,7 +3131,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2695,6 +3135,209 @@ keycompare (struct line const *a, struct +@@ -2693,6 +3132,209 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; }
@@ -3342,7 +3341,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/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. */
-@@ -2722,7 +3365,7 @@ compare (struct line const *a, struct li +@@ -2720,7 +3362,7 @@ compare (struct line const *a, struct li diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3351,7 +3350,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { /* Note xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4113,6 +4756,7 @@ set_ordering (char const *s, struct keyf +@@ -4111,6 +4753,7 @@ set_ordering (char const *s, struct keyf break; case 'f': key->translate = fold_toupper; @@ -3359,7 +3358,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c break; case 'g': key->general_numeric = true; -@@ -4190,7 +4834,7 @@ main (int argc, char **argv) +@@ -4188,7 +4831,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE);
hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3368,7 +3367,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif
-@@ -4211,6 +4855,29 @@ main (int argc, char **argv) +@@ -4209,6 +4852,29 @@ main (int argc, char **argv) thousands_sep = -1; }
@@ -3398,7 +3397,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c have_read_stdin = false; inittables ();
-@@ -4485,13 +5152,34 @@ main (int argc, char **argv) +@@ -4483,13 +5149,34 @@ main (int argc, char **argv)
case 't': { @@ -3437,7 +3436,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4502,9 +5190,12 @@ main (int argc, char **argv) +@@ -4500,9 +5187,12 @@ main (int argc, char **argv) quote (optarg)); } }