fix locale leaks on utf8 strings
authorDavid Mitchell <davem@iabyn.com>
Tue, 16 Apr 2019 14:48:39 +0000 (15:48 +0100)
committerDavid Mitchell <davem@iabyn.com>
Tue, 16 Apr 2019 15:15:56 +0000 (16:15 +0100)
For example the following leaked:

    require POSIX; import POSIX ':locale_h';

    setlocale(&POSIX::LC_ALL, 'aa_DJ.iso88591') or die;
    use locale;

    my $ok = 'A' lt chr 0x100;

Some code in Perl__mem_collxfrm() does a couple of

    for (j = 1; j < 256; j++) { ... }

loops where for each chr(j) character it recursively calls itself, and
records the index of the 'smallest' / 'largest' result. However, when
updating cur_min_x / cur_max_x, it wasn't freeing the previous value.

The symptoms were that valgrind / Address Sanitizer found fault with
lib/locale.t

locale.c

index 81aa00e..8a1ddc2 100644 (file)
--- a/locale.c
+++ b/locale.c
@@ -3951,6 +3951,7 @@ Perl__mem_collxfrm(pTHX_ const char *input_string,
                                  cur_min_x + COLLXFRM_HDR_LEN))
                     {
                         PL_strxfrm_NUL_replacement = j;
+                        safefree(cur_min_x);
                         cur_min_x = x;
                     }
                     else {
@@ -4106,6 +4107,7 @@ Perl__mem_collxfrm(pTHX_ const char *input_string,
                                      cur_max_x + COLLXFRM_HDR_LEN))
                         {
                             PL_strxfrm_max_cp = j;
+                            safefree(cur_max_x);
                             cur_max_x = x;
                         }
                         else {