From: SourceForge.net <no...@so...> - 2007-09-09 23:10:02
|
Bugs item #1791052, was opened at 2007-09-09 17:40 Message generated for change (Comment added) made by flatworm You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=112997&aid=1791052&group_id=12997 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: 18. [text] Group: current: 8.5a6 Status: Open Resolution: None Priority: 9 Private: No Submitted By: Konstantin Khomoutov (flatworm) Assigned to: Jeffrey Hobbs (hobbs) Summary: NULL pointer dereference in LayoutDLine Initial Comment: There's a quite reproducible bug in the Text widget that occurs in Tkabber free XMPP client (http://tkabber.jabber.ru). Unfortunately I have not yet managed to successfully extract the testcase, so here's some background: Tkabber uses Text widgets to render chats, and there embedded images are used to render emoticons (smileys) and mathematical formulae (via the LaTeX plugin). The bug occurs when a window representing a chat session (implemented with the Text widget) is opened and is being initially populated either by chat history or by the message sent to the user that triggered creation of such a window. Then iff the text in that Text widget is happened to contain an embedded image in the last chat message, the bug is almost always triggered. I have managed to narrow the bug: it was most probably introduced with the implementation of TIP #256 since version of 04-Oct-2005 works and one of 11-Oct-2005 crashes. This bug occurs on both Windows and X Window-based systems. 8.4.15 (from ActiveState) is also affected (probably, the implementation has been backported there). I can propose the occurence of this bug does somehow relate to the fact that the Text image in subject ends up being packed in several [grid]s and BWidget's ScrolledWindow which may affect size of the widget in the process of creation of the whole window hierarchy for a chat session. Here's the stack trace (MS VC6): LayoutDLine(TkText * 0x0290bc48, const TkTextIndex * 0x0026fc68) line 1503 + 22 bytes CalculateDisplayLineHeight(TkText * 0x0290bc48, const TkTextIndex * 0x0026fc68, int * 0x0026fc18, int * 0x0026fc1c) line 3429 + 13 bytes TkTextUpdateOneLine(TkText * 0x0290bc48, TkTextLine * 0x0290c080, int 240, TkTextIndex * 0x0026fc68, int 1) line 3595 + 21 bytes TkTextUpdateLineMetrics(TkText * 0x0290bc48, int 0, int 0, int 256) line 2969 + 29 bytes AsyncUpdateLineMetrics(void * 0x0290bc48) line 2789 + 28 bytes TCL85G! 100ca4a8() TCL85G! 100a776f() TCL85G! 100a7b72() Tk_MainLoop() line 2143 + 15 bytes Tk_MainEx(int 3, char * * 0x00b0263c, int (Tcl_Interp *)* 0x00401005 _Tcl_AppInit, Tcl_Interp * 0x00b05070) line 308 WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00292332, int 1) line 129 + 37 bytes WinMainCRTStartup() line 330 + 54 bytes KERNEL32! 7c816d4f() The actual place of dereference is line 1503 at generic/tkTextDisp.c: if (breakChunkPtr == NULL) { /* * This code makes sure that we don't accidentally display chunks with * no characters at the end of the line (such as the insertion * cursor). These chunks belong on the next line. So, throw away * everything after the last chunk that has characters in it. */ breakChunkPtr = lastCharChunkPtr; breakByteOffset = breakChunkPtr->numBytes; } if ((breakChunkPtr != NULL) && ((lastChunkPtr != breakChunkPtr) || (breakByteOffset != lastChunkPtr->numBytes))) { while (1) { chunkPtr = breakChunkPtr->nextPtr; if (chunkPtr == NULL) { break; } FreeStyle(textPtr, chunkPtr->stylePtr); breakChunkPtr->nextPtr = chunkPtr->nextPtr; here -> (*chunkPtr->undisplayProc)(textPtr, chunkPtr); ckfree((char *) chunkPtr); } if (breakByteOffset != breakChunkPtr->numBytes) { (*breakChunkPtr->undisplayProc)(textPtr, breakChunkPtr); segPtr = TkTextIndexToSeg(&breakIndex, &byteOffset); (*segPtr->typePtr->layoutProc)(textPtr, &breakIndex, segPtr, byteOffset, maxX, breakByteOffset, 0, wrapMode, breakChunkPtr); } lastChunkPtr = breakChunkPtr; wholeLine = 0; } P.S. sorry for not presenting a working testcase. If anyone in charge would like to try to run Tkabber so see the bug, feel free to contact me for support. ---------------------------------------------------------------------- >Comment By: Konstantin Khomoutov (flatworm) Date: 2007-09-10 03:10 Message: Logged In: YES user_id=1350198 Originator: YES And one more addition: line reading .t insert end :) emoticon must posess that "emoticon" tag (which makes the text ":)" to be elided), otherwise the bug is not triggered. ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2007-09-10 03:00 Message: Logged In: YES user_id=79902 Originator: NO Thank you very much! That should be enough that we can track down the bug much more easily. Elevating prio to Release Blocker. Do not lower if you are not a Tk maintainer. ---------------------------------------------------------------------- Comment By: Konstantin Khomoutov (flatworm) Date: 2007-09-10 03:00 Message: Logged In: YES user_id=1350198 Originator: YES Addition to the testcase: the line reading .t tag add emoticon_image "end - 2 char" doesn't affect triggering the crash. ---------------------------------------------------------------------- Comment By: Konstantin Khomoutov (flatworm) Date: 2007-09-10 02:38 Message: Logged In: YES user_id=1350198 Originator: YES I have finally extracted a testcase for this bug. This code inserts a text in the widget then installs a mark with the "left" gravity into it, then inserts an "emoticon mnemonic" which is elided, and then finally inserts an emoticon itself (small GIF image). # BEGIN package require Tk image create photo face -data {\ R0lGODlhEgASANUAAAAAAP/////iHP/mIPrWDPraEP/eGPfOAPbKAPbOBPrS CP/aFPbGAPLCAPLGAN62ANauAMylAPbCAPW/APK+AN6uALKNAPK2APK5ANal AOyzArGHBZp3B+6uAHFVBFVACO6qAOqqAOalAMGMAbF+Am1QBG5QBeuiAOad AM6NAJ9vBW1MBFlACFQ9CVlBCuaZAOKVANyVAZlpBMyFAKZtBJVhBEAUEP// /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAADcALAAAAAASABIAAAa+ wJtw+Ckah0iiZwNhODKk0icp/HAShEKBoEBgVFOkK0Iw2GyCs+BAGbGIlrIt EJjXBYgL6X3zJMx1Z2d3EyEmNx9xaYGCdwgaNEUPBYt0do4XKUUOlAOCnmcD CwcXMZsEAgOqq6oLBY+mHxUKBqysCwQSIDNFJAidtgKjFyeRfRQHB2ipAmZs IDArVSTIyoI2bB0oxkIsIxcNyeIXICh7SR8yIhoXFxogJzE1YegrNCkoLzM0 K/RUiEY+tKASBAA7} text .t .t tag configure emoticon -elide 1 .t tag configure emoticon_image -elide 0 if 1 { # (1) .t insert end X } .t mark set MSGLEFT "end - 1 char" if 1 { # (2) .t mark gravity MSGLEFT left } .t insert end :) emoticon if 1 { # (3) .t image create end -image face .t tag add emoticon_image "end - 2 char" } pack .t -fill both -expand true # END Now, how to reproduce. This depends on the state of the "if blocks", labeled "(1)" through "(3)". * Works OK with: 1 2 3 <- block numbers, their states below 0 1 1 1 0 1 1 1 0 * Fails with all blocks enabled. ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2007-09-09 20:56 Message: Logged In: YES user_id=79902 Originator: NO So, the question is how a chunk wound up with a NULL undisplayProc? Or, if that was intended, what should be done in the case that we get to that point? ---------------------------------------------------------------------- Comment By: Don Porter (dgp) Date: 2007-09-09 20:55 Message: Logged In: YES user_id=80530 Originator: NO see also 1056161 and 833627 ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=112997&aid=1791052&group_id=12997 |