• Bug#872002: libxaw7: mixing international and non-international asciiTe

    From Johann Klammer@21:1/5 to All on Sun Aug 13 16:00:02 2017
    XPost: linux.debian.bugs.dist

    This is a multi-part message in MIME format.
    Package: libxaw7
    Version: 2:1.0.12-2
    Severity: normal

    The text widgets have this resource, XtNinternational.
    It is a boolean.
    If it is set to True for one Widget, and False for another,
    a call to XtSetValues to set the text will crash the application.

    compile the testcase using:
    cc -std=gnu99 -DBUG -D_REENTRANT -DDMALLOC_DISABLE -D_FORTIFY_SOURCE=2 -g -Os -fno-common -fstrict-aliasing -fstack-protector -Wall -Wextra -lXext -lX11 -lXt -lXaw ./asciitext.c

    Then:

    gdb ./a.out
    [...]
    (gdb) run
    Starting program: /home/klammerj/projects/fixes/libxaw-1.0.12/debian/patches/a.out

    <click the button>


    Program received signal SIGSEGV, Segmentation fault.
    0xb7d87397 in AsciiPreparePaint (w=0x0, y=2, line=257, from=0, to=26, highlight=0) at ../../src/AsciiSink.c:518
    warning: Source file is more recent than executable.
    518 ascent = XawMax(sink->ascii_sink.font->ascent, ascent);

    (gdb) bt
    #0 0xb7d87397 in AsciiPreparePaint (w=0x0, y=2, line=257, from=0, to=26, highlight=0) at ../../src/AsciiSink.c:518
    #1 0xb7dacb18 in XawTextSinkPreparePaint (w=0x806deb0, y=2, line=0, from=0, to=26, highlight=0) at ../../src/TextSink.c:938
    #2 0xb7da43db in DisplayText (w=0x806ccd8, left=<optimized out>, right=493) at ../../src/Text.c:2792
    #3 0xb7da415c in FlushUpdate (ctx=0x806ccd8) at ../../src/Text.c:3329
    #4 0xb7da8a5b in _XawTextExecuteUpdate (ctx=0x806ccd8) at ../../src/Text.c:3600
    #5 0xb7da9292 in _XawTextSetSource (w=0x806ccd8, source=0x806e1e0, top=<optimized out>, startPos=<optimized out>) at ../../src/Text.c:3891
    #6 0xb7da9712 in XawTextSetSource (w=0x806ccd8, source=0x806e1e0, top=0) at ../../src/Text.c:3901
    #7 0xb7d974f4 in XawMultiSrcSetValues (current=0xbfffdf18, request=0xbfffe238, cnew=0x806e1e0, args=0xbfffeea0, num_args=0xbfffdd4c) at ../../src/MultiSrc.c:840
    #8 0xb7e196a0 in CallSetValues (class=0xb7de2980 <multiSrcClassRec>, current=0xbfffdf18, request=0xbfffe238, new=0x806e1e0, args=0xbfffeea0, num_args=1)
    at ../../src/SetValues.c:133
    #9 0xb7e19a80 in XtSetValues (w=0x806e1e0, args=0xbfffeea0, num_args=1) at ../../src/SetValues.c:269
    #10 0xb7da94a5 in XawTextSetValues (current=0x0, request=0xbfffeb48, cnew=0x806ccd8, args=0xbfffeea0, num_args=0xbfffe61c) at ../../src/Text.c:3709
    #11 0xb7e196a0 in CallSetValues (class=0xb7de4b40 <textClassRec>, current=current@entry=0xbfffe828, request=0xbfffeb48, new=0x806ccd8, args=0xbfffeea0, num_args=1)
    at ../../src/SetValues.c:133
    #12 0xb7e19659 in CallSetValues (class=0xb7de1480 <asciiTextClassRec>, current=0xbfffe828, request=0xbfffeb48, new=0x806ccd8, args=0xbfffeea0, num_args=1)
    at ../../src/SetValues.c:126
    #13 0xb7e19f8b in XtSetValues (w=0x806ccd8, args=0xbfffeea0, num_args=1) at ../../src/SetValues.c:269
    #14 0x08048ddc in set_string (w=0x80654c8, client_data=0x0, call_data=0x0) at ./asciitext.c:53
    #15 0xb7df5027 in XtCallCallbackList (widget=0x80654c8, callbacks=0x8065fb0, call_data=0x0) at ../../src/Callback.c:625
    #16 0xb7d8baad in Notify (w=0x80654c8, event=0xbffff38c, params=0x0, num_params=0x80651b8) at ../../src/Command.c:413
    #17 0xb7e2914c in HandleActions (w=w@entry=0x80654c8, event=0xbffff38c, accelWidget=<optimized out>, procs=0x8069294, actions=<optimized out>, stateTree=<optimized out>)
    at ../../src/TMstate.c:644
    #18 0xb7e29555 in HandleSimpleState (w=w@entry=0x80654c8, tmRecPtr=tmRecPtr@entry=0x80654f8, curEventPtr=0xbffff0b8) at ../../src/TMstate.c:883
    ---Type <return> to continue, or q <return> to quit---
    #19 0xb7e2a493 in _XtTranslateEvent (w=0x80654c8, event=0xbffff38c) at ../../src/TMstate.c:1101
    #20 0xb7e02b9d in XtDispatchEventToWidget (widget=0x80654c8, event=0xbffff38c) at ../../src/Event.c:906
    #21 0xb7e032a0 in _XtDefaultDispatcher (event=0xbffff38c) at ../../src/Event.c:1367
    #22 0xb7e0341b in XtDispatchEvent (event=0xbffff38c) at ../../src/Event.c:1423 #23 0xb7e0f128 in XtAppProcessEvent (app=0x804d868, mask=15) at ../../src/NextEvent.c:1397
    #24 0xb7e0386b in XtAppMainLoop (app=0x804d868) at ../../src/Event.c:1554
    #25 0x08048c91 in main (argc=1, argv=0xbffff5c4) at ./asciitext.c:169


    As far as I can tell the cast at line 440 in AsciiSink.c does the damage.
    (it is actually a MultiSink)
    But it is possible it took a wrong turn at some function pointer further up.

    compile without -DBUG and it will work.(omits the non-intl box)


    #include <unistd.h>
    #include <locale.h>
    #include <errno.h>
    #include <stdarg.h>
    #include <stdint.h>
    #include <math.h>
    #include <wordexp.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <X11/Intrinsic.h>
    #include <X11/Xatom.h>
    #include <X11/Shell.h>
    #include <X11/StringDefs.h>
    #include <X11/Xcms.h>
    #include<X11/Xlib.h>
    #include<X11/extensions/Xdbe.h>
    #include <X11/Xaw/Command.h>
    #include <X11/Xaw/Tree.h>
    #include <X11/Xaw/AsciiText.h>
    #include <X11/Xaw/StripChart.h>
    #include <X11/Xaw/Toggle.h>
    #include <X11/Xaw/Box.h>
    #include <X11/Xaw/Porthole.h>
    #include <X11/Xaw/Viewport.h>
    #include <X11/Xaw/Paned.h>
    #include <X11/Xaw/Dialog.h>
    #include <X11/Xaw/List.h>

    static void quit (Widget w, XEvent * event, String * params,
    Cardinal * num_params);

    static Atom wm_delete_window;
    static XtActionsRec devgui_actions[] = {
    {"quit", quit},
    };

    static char *test = "(Dokumentation, AUT 2011)\n\
    Viermal im Leben umrunden wir in ihnen den Erdball. Sie geben uns Geborgenheit, manchmal quälen sie uns auch: Schuhe. Kein anderes Kleidungsstück hat so viele Spuren in der Menschheitsgeschichte hinterlassen und ist mit so vielen Botschaften und
    Zeichen behaftet. Schuhe erzählen viel von Menschen. Und ihre Macher erst recht: Manolo Blahnik, John Hunter Lobb, Heinrich Staudinger, Diego Rossetti, Nicolas Maistriaux, Gabriele Gmeiner: sechs prominente Meister ihrer Zunft erzählen Schuhgeschichten.
    \n\
    Die sehr persönlichen Sichtweisen der einzelnen Designer ergeben ein komplexes Bild des Handwerks, der einzelnen Charaktere und führen darüber hinaus zu philosophischen Betrachtungen über \"diese Dinge, die wir täglich an unseren Füßen tragen\".\n\
    Regie: Christian Riehs (nach einer Idee von Nikolaus Eder)";

    Widget text;
    static void
    set_string (Widget w, XtPointer client_data,
    XtPointer call_data)
    {
    Arg arglist[20];
    Cardinal i = 0;
    i = 0;
    XtSetArg (arglist[i], XtNstring, test);
    i++;
    XtSetValues (text, arglist, i);
    }

    int
    main (int argc, char **argv)
    {
    Widget top;
    Widget form,cmd;
    Arg arglist[20];
    XtAppContext ctx;
    Cardinal i = 0;
    XtCallbackRec cl[2];

    cl[1].callback = NULL;
    cl[1].closure = NULL;

    cl[0].callback = NULL;
    cl[0].closure = NULL;

    XtSetLanguageProc(NULL, NULL, NULL);

    i = 0;
    XtSetArg (arglist[i], XtNwidth, 600);
    i++;
    XtSetArg (arglist[i], XtNheight, 400);
    i++;
    top =
    XtAppInitialize (&ctx, "Top", 0, 0, &argc, argv, NULL, arglist,
    i);
    i = 0;
    form =
    XtCreateManagedWidget ("Form", formWidgetClass, top, arglist, i);

    cl[0].callback = set_string;
    cl[0].closure = NULL;

    i = 0;
    XtSetArg (arglist[i], XtNleft, XawChainLeft);
    i++;
    XtSetArg (arglist[i], XtNright, XawChainLeft);
    i++;
    XtSetArg (arglist[i], XtNtop, XawChainTop);
    i++;
    XtSetArg (arglist[i], XtNbottom, XawChainTop);
    i++;
    XtSetArg (arglist[i], XtNcallback, cl);
    i++;
    cmd=XtCreateManagedWidget ("Set1", commandWidgetClass, form,
    arglist, i);

    i = 0;
    XtSetArg (arglist[i], XtNleft, XawChainLeft);
    i++;
    XtSetArg (arglist[i], XtNright, XawChainRight);
    i++;
    XtSetArg (arglist[i], XtNtop, XawChainTop);
    i++;
    XtSetArg (arglist[i], XtNbottom, XawChainTop);
    i++;
    XtSetArg (arglist[i], XtNfromVert, cmd);
    i++;
    XtSetArg (arglist[i], XtNheight, 110);
    i++;
    XtSetArg (arglist[i], XtNwidth, 520);
    i++;
    XtSetArg (arglist[i], XtNtype, XawAsciiString);
    i++;
    XtSetArg (arglist[i], XtNstring, NULL);
    i++;
    XtSetArg (arglist[i], XtNscrollVertical, XawtextScrollAlways);
    i++;
    XtSetArg (arglist[i], XtNwrap, XawtextWrapWord);
    i++;
    XtSetArg (arglist[i], XtNinternational, True);
    i++;
    text =
    XtCreateManagedWidget ("TXT", asciiTextWidgetClass, form, arglist, i);

    #ifdef BUG
    i = 0;
    XtSetArg (arglist[i], XtNleft, XawChainLeft);
    i++;
    XtSetArg (arglist[i], XtNright, XawChainRight);
    i++;
    XtSetArg (arglist[i], XtNtop, XawChainTop);
    i++;
    XtSetArg (arglist[i], XtNbottom, XawChainBottom);
    i++;
    XtSetArg (arglist[i], XtNfromVert, text);
    i++;
    XtSetArg (arglist[i], XtNheight, 110);
    i++;
    XtSetArg (arglist[i], XtNwidth, 520);
    i++;
    XtSetArg (arglist[i], XtNtype, XawAsciiString);
    i++;
    XtSetArg (arglist[i], XtNstring, NULL);
    i++;
    XtSetArg (arglist[i], XtNscrollVertical, XawtextScrollAlways);
    i++;
    XtSetArg (arglist[i], XtNwrap, XawtextWrapWord);
    i++;
    XtSetArg (arglist[i], XtNinternational, False);
    i++;
    XtCreateManagedWidget ("TXT2", asciiTextWidgetClass, form, arglist, i); #endif

    XtAppAddActions (ctx, devgui_actions, XtNumber (devgui_actions));
    XtOverrideTranslations (top,
    XtParseTranslationTable
    ("<Message>WM_PROTOCOLS: quit()"));
    XtRealizeWidget (top);
    XtMapWidget (top);

    wm_delete_window = XInternAtom (XtDisplay (top), "WM_DELETE_WINDOW", False);
    XSetWMProtocols (XtDisplay (top), XtWindow (top), &wm_delete_window, 1);
    XtAppMainLoop (ctx);
    XtDestroyApplicationContext (XtWidgetToApplicationContext (top));
    return 0;
    }

    static void
    quit (Widget w, XEvent * event, String * params, Cardinal * num_params)
    {
    if (event->type == ClientMessage &&
    event->xclient.data.l[0] != wm_delete_window)
    {
    XBell (XtDisplay (w), 0);
    return;
    }
    XtAppSetExitFlag (XtWidgetToApplicationContext (w));
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Johann Klammer@21:1/5 to All on Wed Sep 6 07:00:01 2017
    XPost: linux.debian.bugs.dist

    The control flow diverges somewhere after FlushUpdate...
    it seems to be this if.. in Text.c

    3320 #ifndef OLDXAW
    3321 if (XawTextSinkBeginPaint(ctx->text.sink) == False)
    3322 #endif
    3323 display_text = OldDisplayText;

    the condition differs because of:
    XawTextSinkBeginPaint

    in the working code,
    cclass->text_sink_class.extension->PreparePaint
    and DoPaint are NULL
    and
    display_text = OldDisplayText;

    the broken code has:
    (gdb) p cclass->text_sink_class.extension->BeginPaint
    $3 = (int (*)(Widget)) 0xb7dabe40 <BeginPaint>
    (gdb) p cclass->text_sink_class.extension->PreparePaint
    $4 = (void (*)(Widget, int, int, XawTextPosition, XawTextPosition,.
    int)) 0xb7d86770 <AsciiPreparePaint>
    (gdb) p cclass->text_sink_class.extension->DoPaint
    $5 = (void (*)(Widget)) 0xb7d84b90 <AsciiDoPaint>
    (gdb) p cclass->text_sink_class.extension->EndPaint
    $6 = (int (*)(Widget)) 0xb7dab920 <EndPaint>

    those get set in
    XawAsciiSinkClassPartInitialize in AsciiSink.c

    .extension gets set in:
    XawTextSinkClassPartInitialize in TextSink.c

    It's the TextSinkExtensionRec is /defined static/ in TextSink.c
    Therefore initializing a single non-intl textbox (by XawAsciiSinkClassPartInitialize) breaks all the intl boxes.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)