Tue 11 Jul 2006 03:28:13 PM UTC, original submission:
On the default main window of synaptic, in the Description column (where the short description, i.e. the first line of the corresponding deb field) is displayed, if you move the mouse around over the packages listed here, the end of the summaries are randomly (quite often) redisplayed falsely: a stupid letter appears around the 50th--70th character position, and the string unexpectedly ends there. The same display problem also often occurs in the lower part of the window (where the full description is displayed) if I click on the row of a package.
I attach two screenshots, I did nothing between shooting them except for moving the mouse over the synaptic window.
The reason of the buggy behavior is the following:
In gtk/gtkpkglist.cc:441 the summary() function is called and later the result is displayed. The summary() function is implemented at common/rpackage.cc:123 which in turn calls apt's ShortDesc().
libapt's ShortDesc() returns a correct "string" containing the short description. The summary() function turns this "string" to a "char " using c_str(). The result is valid as long as the "string" is available (since it's actually a pointer to somewhere inside the "string" object.) When this summary() function returns, the string ceases to exist. Hence the returned "char " refers to a memory area that happens to contain the required summary right now, but is not officially allocated, so anyone is allowed to overwrite it at any time. On my particular system (Linux, i586, apt-0.6.44, synaptic-0.57.2, glibc-2.4, gcc-3.4.6 etc.) it occurs very often that the end of the strings get overwritten even before the retval is used in gtkpkglist.cc (before it calls utf8() on the result). Obviously, the behavior can be very different on other systems.
Note that many other functions next to section() (e.g. srcPackage(), maintainer()) suffer from exactly the same problem.
Suggested solution:
These functions should return a "string" instead of "char *". When the return value is being used, it would still be false to write something(summary().c_str()) due to exactly the same reason discussed above, so we need to make sure the string is still available when something() is called. So here's an example of the right usage in gtkpkglist.cc:
case DESCR_COLUMN:
string foo = pkg->summary();
str = utf8(foo.c_str());
g_value_set_string(value, str);
the declaration of "string foo" makes sure that it still exists when its value (as a "char *") is displayed on the screen.
Suggested solution #2:
Use strdup() inside summary() and the caller should free the result.
|