summaryrefslogtreecommitdiff
path: root/src/csplit.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2003-11-16 12:25:35 +0000
committerJim Meyering <jim@meyering.net>2003-11-16 12:25:35 +0000
commit51ab3265f8444eeb09faf47c9d5d4a1a8b036025 (patch)
treedfbad0fb1119aab39ac73cf025204f8641a24fad /src/csplit.c
parent8560d7254ba1cbf29f5b6941e65c1619c01b33a6 (diff)
downloadcoreutils-51ab3265f8444eeb09faf47c9d5d4a1a8b036025.tar.xz
Fix read-from-free'd-buffer error detected by valgrind.
(remove_line): Don't return a pointer to data in a freed buffer. Instead, arrange to free the buffer on the subsequent call.
Diffstat (limited to 'src/csplit.c')
-rw-r--r--src/csplit.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/csplit.c b/src/csplit.c
index d2294b90e..dca288408 100644
--- a/src/csplit.c
+++ b/src/csplit.c
@@ -526,9 +526,20 @@ get_first_line_in_buffer (void)
static struct cstring *
remove_line (void)
{
+ /* If non-NULL, this is the buffer for which the previous call
+ returned the final line. So now, presuming that line has been
+ processed, we can free the buffer and reset this pointer. */
+ static struct buffer_record *prev_buf = NULL;
+
struct cstring *line; /* Return value. */
struct line *l; /* For convenience. */
+ if (prev_buf)
+ {
+ free_buffer (prev_buf);
+ prev_buf = NULL;
+ }
+
if (head == NULL && !load_buffer ())
return NULL;
@@ -548,10 +559,11 @@ remove_line (void)
head->curr_line = l->next;
if (head->curr_line == NULL || head->curr_line->used == 0)
{
- /* Go on to the next data block. */
- struct buffer_record *b = head;
+ /* Go on to the next data block.
+ but first record the current one so we can free it
+ once the line we're returning has been processed. */
+ prev_buf = head;
head = head->next;
- free_buffer (b);
}
}