[comp.windows.x] Infinite recursion bug in Xt

tml@hemuli.tik.vtt.fi (Tor Lillqvist) (08/03/90)

I ran across something that seems like an infinite recursion bug in
Xt:

Look at Intrinsic.c:_XtWindowedAncestor:

    if (object == NULL) {
	String params = XtName(object);
	Cardinal num_params = 1;
	XtAppErrorMsg(XtWidgetToApplicationContext(object),
		      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
		   "noWidgetAncestor", "windowedAncestor", XtCXtToolkitError,
		   "Object \"%s\" does not have windowed ancestor",
		   &params, &num_params);
    }


Now look at Display.c:XtWidgetToApplicationContext:

	return _XtGetPerDisplay(XtDisplayOfObject(w))->appContext;
				^^^^^^^^^^^^^^^^^^^^

And then IntrinsicI.h:

#define XtDisplayOfObject(object) \
    ((XtIsWidget(object) ? (object) : _XtWindowedAncestor(object)) \
				      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
     ->core.screen->display)


As yo notice, you _XtWindowedAncestor and XtWidgetToApplicationContext
will call each other infinitely...  I got a (huge) core dump when playing
with xtex.
-- 
Tor Lillqvist,
working, but not speaking, for the Technical Research Centre of Finland

swick@ATHENA.MIT.EDU (Ralph Swick) (08/03/90)

Oops.  how embarassing.  Coffee must have been on-order that day.

Here's the obvious patch, in case you can't wait for the next
set of public fixes:

*** /tmp/,RCSt1a03903	Fri Aug  3 11:15:51 1990
--- Intrinsic.c	Fri Aug  3 11:14:41 1990
***************
*** 572,587 ****
   * Internal routine; must be called only after XtIsWidget returns false
   */
  Widget _XtWindowedAncestor(object)
! 	Widget object;
  {
      for (object = XtParent(object); object && !XtIsWidget(object);)
  	object = XtParent(object);
  
      if (object == NULL) {
! 	String params = XtName(object);
  	Cardinal num_params = 1;
! 	XtAppErrorMsg(XtWidgetToApplicationContext(object),
! 		   "noWidgetAncestor", "windowedAncestor", XtCXtToolkitError,
  		   "Object \"%s\" does not have windowed ancestor",
  		   &params, &num_params);
      }
--- 572,587 ----
   * Internal routine; must be called only after XtIsWidget returns false
   */
  Widget _XtWindowedAncestor(object)
!     register Widget object;
  {
+     Widget obj = object;
      for (object = XtParent(object); object && !XtIsWidget(object);)
  	object = XtParent(object);
  
      if (object == NULL) {
! 	String params = XtName(obj);
  	Cardinal num_params = 1;
! 	XtErrorMsg("noWidgetAncestor", "windowedAncestor", XtCXtToolkitError,
  		   "Object \"%s\" does not have windowed ancestor",
  		   &params, &num_params);
      }