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));
}
}
--
1.8.3.1