csplit: fix a memory leak per input buffer

* src/csplit.c (free_buffer): Also free the line offsets buffers
(remove_line): Also free the containing structure
* tests/misc/csplit-heap: A new test to trigger with leaks of
this magnitude.
* tests/Makefile.am: Reference the new test
* NEWS: Mention the fix
Reported by David Hofstee
This commit is contained in:
Pádraig Brady 2010-11-10 14:35:17 +00:00
parent 7727908335
commit 0339eb4598
4 changed files with 41 additions and 3 deletions

6
NEWS
View File

@ -9,9 +9,9 @@ GNU coreutils NEWS -*- outline -*-
latent bug introduced in coreutils 8.1, and possibly a second latent
bug going at least as far back as coreutils 5.97]
csplit no longer corrupts heap when writing more than 999 files.
Demonstrate with: seq 1000 | csplit - /./ '{*}'
[the bug was present in the initial implementation]
csplit no longer corrupts heap when writing more than 999 files,
nor does it leak memory for every chunk of input processed
[the bugs were present in the initial implementation]
tail -F once again notices changes in a currently unavailable
remote directory [bug introduced in coreutils-7.5]

View File

@ -418,6 +418,13 @@ get_new_buffer (size_t min_size)
static void
free_buffer (struct buffer_record *buf)
{
struct line *l;
for (l = buf->line_start; l;)
{
struct line *n = l->next;
free (l);
l = n;
}
free (buf->buffer);
buf->buffer = NULL;
}
@ -542,6 +549,7 @@ remove_line (void)
if (prev_buf)
{
free_buffer (prev_buf);
free (prev_buf);
prev_buf = NULL;
}

View File

@ -173,6 +173,7 @@ TESTS = \
misc/comm \
misc/csplit \
misc/csplit-1000 \
misc/csplit-heap \
misc/date-sec \
misc/dircolors \
misc/df \

29
tests/misc/csplit-heap Executable file
View File

@ -0,0 +1,29 @@
#!/bin/sh
# ensure that csplit uses a bounded amount of memory
# Copyright (C) 2010 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
. "${srcdir=.}/init.sh"; path_prepend_ ../src
test "$VERBOSE" = yes && csplit --version
require_ulimit_
(
ulimit -v 20000
{ yes | head -n2500000; echo n; } | csplit -z - %n%1
) || fail=1
Exit $fail