[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: bash 2.04 possible TERM variable bug?
From: |
Chet Ramey |
Subject: |
Re: bash 2.04 possible TERM variable bug? |
Date: |
Thu, 1 Feb 2001 10:44:00 -0500 |
> Chet Ramey wrote:
>
> >
> > I can't reproduce this on FreeBSD or Linux with the current development
> > version of bash-2.05, so I'm going to assume it's fixed. (I can reproduce
> > it on Linux with bash-2.04).
> >
> > Chet
>
> Phew.. I wasn't sure if it was another strange Red Hat 7 phenomenon.
It is, in fact, a strange Red Hat phenomenon. I can reproduce it on
Red Hat 6. When tgetent(3) finds a valid termcap entry for the
desired terminal, it ignores the buffer passed by the caller to hold
the termcap entry and allocates its own. This wouldn't be so bad if
it didn't set an internal pointer to the buffer argument passed by the
caller, and then free it later.
Under certain circumstances (exactly those from your bug report -- what a
coincidence), tgetent() does the following:
TERM=vt220
1. it gets a valid terminal name, ignores the buffer passed by the caller,
allocates its own storage for the terminal capability buffer, sets a
`we malloced it' flag, and sets an internal pointer to this freshly-
allocated buffer.
TERM=-
2. it gets an invalid terminal name, for which it cannot find an entry in
the termcap database, sets the same internal pointer to point to the
termcap capability buffer passed by the caller as the first argument,
and returns failure. Note that it does not reset the `we malloced it'
flag to 0 here. Readline then frees the buffer it allocated and passed
to tgetent, since it should not have anything useful, and sets its own
pointer to 0.
TERM=vt220
3. Readline allocates a new buffer for the termcap entry, which happens to
have the same address as the one just freed in step 2.
4. tgetent gets a valid terminal name, frees the storage pointed to by that
same pesky internal pointer (since the `we malloced it' flag is still 1),
reallocates its own internal capability buffer, reads the termcap entry
into it, and returns 1. Note that because of what it did in step 2, and
the fact that readline's new termcap buffer has the same address as it
did before, it's just freed memory out from underneath the caller.
TERM=-
4. tgetent gets an invalid terminal name, does the same stuff as in step 2,
and returns failure. Readline again frees the buffer it allocated for
the termcap entry, since it should not contain anything useful, thereby
freeing memory twice. The bash malloc really doesn't like it when you
free memory multiple times, and aborts.
Red Hat could fix this by resetting the `we malloced it' flag to 0 when it
doesn't find a termcap entry for the terminal name and sets its internal
pointer to the buffer passed by the application.
Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
( ``Discere est Dolere'' -- chet)
Chet Ramey, CWRU chet@po.CWRU.Edu http://cnswww.cns.cwru.edu/~chet/