Package: xaw3dg
Version:  1.5+E-14

When 'xfig' version 3.2.5 is configured to use Xaw3d, the xfig program locks 
up in an infinite loop when the 'T' (for text) button is clicked after 
program startup.

The problem in a function used for layouts, Box.c:PreferredSize():line 354, in 
this code:

            unsigned int width = preferred_width;
            do { /* find some width big enough to stay within this height */
                width *= 2;
                if (width > constraint->width) width = constraint->width;
                DoLayout(w, width, 0, &preferred_width, &preferred_height, 
FALSE);
            } while (preferred_height > constraint->height &&
                     width < constraint->width);

The problem is that for the case "request_mode == CWHeight", the value 
of 'constraint->width has been set to 0xffff, and DoLayout() will always 
set 'preferred_height' to the same value.  The value assigned 
to 'preferred_height' will be the same as the earlier call to DoLayout() at 
line 344, so we know that "preferred_height > constraint->height".  The 
variable 'width' has type "unsigned short", so eventually, the 
multiplication "width *= 2" overflows, and the value of "width" will become 
zero.

This became a problem in the 3.2.5 version of xfig, when the calls:

                update_indpanel(0);     /* first remove ind buttons */
                XtUnmanageChild(ind_panel);

at about line 616 became unconditionally executed.  The Viewport 
widget 'ind_panel' no longer has any widgets to layout, and the height of the 
viewport's inner window is set to a size smaller than the Viewport widget.  I 
think that makes sense. 

But an optimization introduced by D. J. Hawkey Jr. in the "E" version changed 
the way clipping works in Viewport.c:ComputeLayout().  The conditional 
PREP_CHILD_TO_CLIP is not defined, and the variable 'intended.height' is 
assigned a value from the child (viewport inner window) height, rather than 
the clip_width value computer from the widget height.

It's not clear to me whether the changes to Viewport.c:ComputeLayout() are 
valid or not, but it is clear that the Box.c loop is wrong.  So I prefer to 
leave Mr. Hawkey's changes in place, and fix the Box.c code (which hasn't 
changed from the older X11 version (Release 1.5; 14 May, 1998)

A note to "[EMAIL PROTECTED]" bounced, and then I found this reference that 
indicates that unfortunately Mr. Hawkey passed away:

http://packages.debian.org/changelogs/pool/main/v/vtwm/vtwm_5.4.7-2.1/changelog

So I'm sending a patch to you, hoping that it can get included.  Here's a 
patch that will fix the problem:

*** Box.c~      1996-10-15 10:41:18.000000000 -0400
--- Box.c       2007-04-21 14:12:44.000000000 -0400
***************
*** 353,360 ****
        else {
            width = preferred_width;
            do { /* find some width big enough to stay within this height */
!               width *= 2;
!               if (width > constraint->width) width = constraint->width;
                DoLayout(w, width, 0, &preferred_width, &preferred_height, 
FALSE);
            } while (preferred_height > constraint->height &&
                     width < constraint->width);
--- 353,363 ----
        else {
            width = preferred_width;
            do { /* find some width big enough to stay within this height */
!               if (width > constraint->width/2) /* avoid short int overflow 
*/
!                   width = constraint->width;
!               else
!                   width *= 2;
! 
                DoLayout(w, width, 0, &preferred_width, &preferred_height, 
FALSE);
            } while (preferred_height > constraint->height &&
                     width < constraint->width);
*** Box.c~	1996-10-15 10:41:18.000000000 -0400
--- Box.c	2007-04-21 14:12:44.000000000 -0400
***************
*** 353,360 ****
  	else {
  	    width = preferred_width;
  	    do { /* find some width big enough to stay within this height */
! 		width *= 2;
! 		if (width > constraint->width) width = constraint->width;
  		DoLayout(w, width, 0, &preferred_width, &preferred_height, FALSE);
  	    } while (preferred_height > constraint->height &&
  		     width < constraint->width);
--- 353,363 ----
  	else {
  	    width = preferred_width;
  	    do { /* find some width big enough to stay within this height */
! 		if (width > constraint->width/2) /* avoid short int overflow */
! 		    width = constraint->width;
! 		else
! 		    width *= 2;
! 
  		DoLayout(w, width, 0, &preferred_width, &preferred_height, FALSE);
  	    } while (preferred_height > constraint->height &&
  		     width < constraint->width);

Reply via email to