tgetstr() is documented as taking as one of its arguments a buffer area where it will place the extracted string entry (it also returns a pointer to this area as its return value). In 6.1, tgetstr() does NOT use this area; it appears to make up its own area and return that instead. This BREAKS code of the form: char buf[100], *bufp = buf; if (tgetstr(capability, &bufp) != NULL) tputstr(buf, 1, myputchar); which is perfectly valid code that is found in some of the programs we use here. Worse yet, not even the minor library version has changed. Worse still, if this area is dynamically allocated (the info file suggests by implication that it may be), any programs using tgetstr() repeatedly, even if they work, are leaking memory -- since they don't expect to need to free the result, and indeed freeing the result is an error with the old library.
As a followup note: I have an (obvious) test program to demonstrate this problem, and to show how it makes valid code print really whacky garbage. The same test program -- even the same BINARY -- works fine with the 6.0 libtermcap library. If you want a copy I will attach it to this bug report.
Which documentation states tgetstr() should accept this? (The man page in ncurses definitely doesn't). The changelog of the libtermcap package actually documents the change as a bugfix, so I believe your code is relying on some other-OS specific function. "Fixing" it is a matter of removing one patch, so if you can convince me that it's the right thing to do, it can be done quickly.
See 'info --file=/usr/info/termcap.info.gz' and search for tgetstr(). This is also the historical behavior, as documented in the manpages on other systems. In fact, this is the behavior specified in the Single Unix Specification; see the URL: http://www.opengroup.org/onlinepubs/007908799/xcurses/tgetent.html which says specifically 'If area is not a null pointer and does not point to a null pointer, tgetstr() copies the string entry into the buffer pointed to by *area [...]'.
Using this buffer causes problems. The amount that the terminal library would write is a somewhat undocumented custom; if this ever changes (for example, if termcap entries get longer), you run the risks of exploding any program that uses tgetstr, some of which might be running setuid/setgid. Hence, termcap was changed to ignore the buffer parameter, much as ncurses does.
There are two major problems with the argument that this is better. First: this change contradicts both the libtermcap documentation for tgetstr() and its Single Unix Standard specification. Indeed both sets of documentation tell how to achieve this safety. I don't consider gratuitous deviations from a standard in the interests of nominal application safety to be a particularly good thing; what's next, making gets() not work? After all, it's unsafe too. Second, and more severe: THIS IS AN INCOMPATABLE ABI CHANGE. The Redhat 6.1 libtermcap.so library does not implement the same ABI that the 6.0 libtermcap.so implements, and does so without even a MINOR version number change, much less the proper major version number change. This change can, will, and DOES break applications, such as some we have. No matter how improved the library is, if it does not have the same ABI it should not have the same major and minor revision number as the 6.0 libtermcap, because applications that worked perfectly under 6.0, and were written in accordance with the available documentation, *BREAK UNDER THE CHANGE*. If Redhat is going to change the ABI, it should change the major version number of the library, and it should change the documentation so that people know what changed. In the abscence of this, I strongly believe that Redhat has an obligation to honor the existing ABI: ie, reverse the change and issue an updated shared library that has the 6.0 ABI.
We've just had another internal discussion about it, and come to the conclusion that the new behavior is correct and MUCH better security-wise.