Package: xgammon
Version: 0.99.1128-3
Severity: important
Tags: patch


-- System Information:
Debian Release: squeeze/sid
  APT prefers karmic-updates
  APT policy: (500, 'karmic-updates'), (500, 'karmic-security'), (500, 'karmic')
Architecture: i386 (i686)

Kernel: Linux 2.6.31-17-generic (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages xgammon depends on:
ii  libc6                2.10.1-0ubuntu15    GNU C Library: Shared libraries
ii  libice6              2:1.0.5-1           X11 Inter-Client Exchange library
ii  libsm6               2:1.1.0-2           X11 Session Management library
ii  libx11-6             2:1.2.2-1ubuntu1    X11 client-side library
ii  libxaw7              2:1.0.6-1           X11 Athena Widget library
ii  libxext6             2:1.0.99.1-0ubuntu4 X11 miscellaneous extension librar
ii  libxt6               1:1.0.5-3ubuntu1    X11 toolkit intrinsics library

xgammon recommends no packages.

xgammon suggests no packages.

-- no debconf information

It takes a while to get this SIGSEGV to occur.  On my machine,
running a computer-vs-computer game it takes about 30 minutes.

The failure is due to an overflow of the DialogText string
in diawin.c.  I recompiled the source with debugging turned on
and found the following:

Failing source line:  165  while (DialogText[i] != '\n') i++;

Variable: i = 38080
          lastPos = 59986
          

After inserting some debug printf statements in the code, I
determined that with XtNeditType = XawtextAppend, the call
to XawTextReplace is failing with a non-zero return code.

The Athena Documentation says that XawTextReplace on an
XawtextAppend object can only replace the text at the end
of the buffer.  Since this XawTextReplace is trying to
delete data at the beginning of the buffer, it fails.

To fix the problem, I put the object into XawtextEdit while
doing the XawTextReplace and then set it back to XawtextAppend.

This fixes the problem.  I also found another problem with
the line:  while (DialogText[i] != '\n') i++;

This line assumes that we are referencing DialogText.  But
this is only true if where == LOWER.  I also fixed that bug.

Here is the complete AppendDialogText that works.


void AppendDialogText (int where, char *s)
{
        XawTextPosition i, lastPos;
        XawTextBlock    textblock, nullblock;

        Widget w;

        char *text_buffer;
        XawTextEditType type;

        if      (where == UPPER) {
                w   =         Player[0].X11Set.tournament_display;
                text_buffer = TournamentText;
        } else if (where == LOWER) {
                w   =         Player[0].X11Set.text_display;
                text_buffer = DialogText;
        } else {
                fprintf (stderr, "unkown widget for AppendDialogText ()\n");
                return;
        }

        if (!s || !strcmp(s, "")) return;

        textblock.firstPos = 0;
        textblock.length   = strlen(s);
        textblock.ptr      = s;

        lastPos = TextGetLastPos (w);
        if (textblock.length > DIALOGSIZE) {
                fprintf (stderr, "xgammon error: cannot display string in 
dialogue window\n\
                        string has %d bytes; dialogue window size limit is %d 
bytes\n",
                        textblock.length, DIALOGSIZE);
                return;
        }
        if (lastPos + textblock.length > DIALOGSIZE) {
                nullblock.firstPos = 0;
                nullblock.length   = 0;
                nullblock.ptr      = "";

                i = textblock.length - (DIALOGSIZE - lastPos);
                if (i < 0.9*DIALOGSIZE) i += 0.1*DIALOGSIZE;
                while (text_buffer[i] != '\n') i++;
                XtVaGetValues(w, XtNeditType, (XtArgVal) &type, NULL);
                XtVaSetValues(w, XtNeditType, XawtextEdit, NULL);
                XawTextReplace (w, 0, i, &nullblock);
                XtVaSetValues(w, XtNeditType, (XtArgVal) type, NULL);
                lastPos = TextGetLastPos (w);
        }
        XawTextReplace (w, lastPos, lastPos, &textblock);
        InputPos = TextGetLastPos (w);
        if (where == UPPER) lt = InputPos;
        XawTextSetInsertionPoint (w, InputPos);
        if (gammon_resource.protokol) fprintf(protokol_file, "%s", s);

        if (gammon_resource.other_display) {

        if      (where == UPPER) {
                w   =         Player[1].X11Set.tournament_display;
                text_buffer = TournamentText;
        } else if (where == LOWER) {
                w   =         Player[1].X11Set.text_display;
                text_buffer = DialogText;
        } else {
                fprintf (stderr, "unkown widget for AppendDialogText ()\n");
                return;
        }

        if (!s || !strcmp(s, "")) return;

        textblock.firstPos = 0;
        textblock.length   = strlen(s);
        textblock.ptr      = s;

        lastPos = TextGetLastPos (w);
        if (textblock.length > DIALOGSIZE) {
                fprintf (stderr, "xgammon error: cannot display string in 
dialogue window\n\
                        string has %d bytes; dialogue window size limit is %d 
bytes\n",
                        textblock.length, DIALOGSIZE);
                return;
        }
        if (lastPos + textblock.length > DIALOGSIZE) {
                nullblock.firstPos = 0;
                nullblock.length   = 0;
                nullblock.ptr      = "";

                i = textblock.length - (DIALOGSIZE - lastPos);
                if (i < 0.9*DIALOGSIZE) i += 0.1*DIALOGSIZE;
                while (text_buffer[i] != '\n') i++;
                XtVaGetValues(w, XtNeditType, (XtArgVal) &type, NULL);
                XtVaSetValues(w, XtNeditType, XawtextEdit, NULL);
                XawTextReplace (w, 0, i, &nullblock);
                XtVaSetValues(w, XtNeditType, (XtArgVal) type, NULL);
                lastPos = TextGetLastPos (w);
        }
        XawTextReplace (w, lastPos, lastPos, &textblock);
        InputPos = TextGetLastPos (w);
        if (where == UPPER) lt = InputPos;
        XawTextSetInsertionPoint (w, InputPos);

        }
}



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to