After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 54838 - Gimp Segment Fault on Add-Bevel Script
Gimp Segment Fault on Add-Bevel Script
Status: RESOLVED DUPLICATE of bug 9350
Product: GIMP
Classification: Other
Component: Script-Fu
1.x
Other Linux
: Normal major
: ---
Assigned To: Garry R. Osgood
Daniel Egger
Depends on:
Blocks:
 
 
Reported: 2001-05-17 15:26 UTC by thomas.carlisle
Modified: 2001-06-02 14:59 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description thomas.carlisle 2001-05-17 15:26:15 UTC
Gimp Version: 1.2.1
glib version: 1.2.10 (currently from ximian RPM, but also have tried with
RedHat rpm, and also glib 1.2.10 compiled from source)
Gtk+ version: 1.2.10 (currently from ximian RPM, but also have tried with
RedHat rpm version, and also compiled from source)
Xfree86: 4.0.1 from RedHat RPM
Glibc: 2.2

If I try to add a bevel to any text, I get a segment fault. For example, if
I launch Gimp, start a new file, then select the text tool to insert the
word "Testing" (font and font-size don't seem to make a difference, but I
usually use times at 24pts), then with the newly inserted text still
highlighted I right-click, select Script-Fu|Decor|Bevel.... I leave the
defualts, and right after the part where the script does the bump map, Gimp
crashes with a segmentation fault.

I have also seen this problem on RedHat 6.2.

Here is a snapshot of the errors just prior to the crash, and the stack
trace following the crash:

Gtk-WARNING **: invalid cast from `(unknown)' to `GimpDrawable'

Gtk-WARNING **: invalid cast from `(unknown)' to `GimpDrawable'

Gtk-WARNING **: invalid cast from `(unknown)' to `GimpDrawable'

Gtk-WARNING **: invalid cast from `(unknown)' to `GimpDrawable'

Gtk-WARNING **: invalid cast from `(unknown)' to `GimpDrawable'

Gtk-WARNING **: invalid cast from `(unknown)' to `GimpDrawable'

Gimp-CRITICAL **: file gimpdrawable.c: line 635 (gimp_drawable_width): 
assertion
 `GIMP_IS_DRAWABLE (drawable)' failed.
gimp: fatal error: Segmentation fault
gimp (pid:31438): [E]xit, [H]alt, show [S]tack trace or [P]roceed: S
  • #0 g_on_error_stack_trace
  • #1 g_on_error_query
    at gerror.c line 133
  • #2 gimp_fatal_error
  • #3 <signal handler called>
  • #4 tile_detach
    at tile.c line 341
  • #5 tile_manager_destroy
    at tile_manager.c line 73
  • #6 floating_sel_store
  • #7 floating_sel_rigor
  • #8 crop_image
  • #9 crop_invoker
    at tools_cmds.c line 1103
  • #10 procedural_db_execute
  • #11 plug_in_handle_proc_run
    at plug_in.c line 1706
  • #12 plug_in_recv_message
  • #13 g_io_unix_dispatch
  • #14 g_main_dispatch
    at gmain.c line 656
  • #15 g_main_iterate
    at gmain.c line 877
  • #16 g_main_run
    at gmain.c line 935
  • #17 gtk_main
    at gtkmain.c line 524
  • #18 main
    at main.c line 403
  • #19 __libc_start_main

Comment 1 Raphaël Quinet 2001-05-18 16:04:54 UTC
I can reproduce this crash easily.  Note that it only works if you
run the Add Bevel script before anchoring the layer.  Running the
script on a floating selection is apparently what causes the crash.
The font size and other parameters do not really matter.
Comment 2 Garry R. Osgood 2001-05-20 00:09:54 UTC
The script add-bevel.scm fails at crop-image when
the layer to be beveled is (1) small, (2) has a very
large offset from the upper left hand corner of the 
containing image, (3) is a floating layer, and (4)
the user is requesting to work on an image copy. 

This array of conditions can be reproduced without
using the text tool; any floating layer that has
smaller width or height than the layer's current x or y
offset will prompt a crash.

crop_image() (crop.c CVS-1.61 line 823) will cull
layers immediately if Undo has been disabled for the
containing GimpImage and the result of the crop leaves
a layer's width or height zero.  The floating layer
will be culled as well; unfortunately, crop_image
persists a dangling pointer to the floating layer, and
continues to operate on it. This is the immediate cause
of the crash.

The condition of Undo being disabled arises from
requesting that the AddBevel script operate on a copy
image. The script disables undo for the new copy image
for the duration of the script run.

Garry Osgood


Point of failure: (Search for !!!)
------------------------------------------------------
!!!-1  width and height will be zero for small layers
!!!-2  with large x and y offsets   
!!!-3  Layer with zero resultant layer width or height are culled here
!!!-4  This floating selection may be a dangling reference to a culled 
       layer; if so, the memory region likely points to something not
       recognizable as a layer.

 void
crop_image (GImage   *gimage,
	    gint      x1,
	    gint      y1,
	    gint      x2,
	    gint      y2,
	    gboolean  layer_only,
	    gboolean  crop_layers)
{
  Layer   *layer;
  Layer   *floating_layer;
  Channel *channel;
  GList   *guide_list_ptr;
  GSList  *list;
  gint width, height;
  gint lx1, ly1, lx2, ly2;
  gint off_x, off_y;
  gint doff_x, doff_y;

  width = x2 - x1;
  height = y2 - y1;

  /*  Make sure new width and height are non-zero  */
  if (width && height)
    {
      gimp_add_busy_cursors ();

      if (layer_only)
	{
	  undo_push_group_start (gimage, LAYER_RESIZE_UNDO);

	  layer = gimage->active_layer;

	  if (layer_is_floating_sel (layer))
	    floating_sel_relax (layer, TRUE);

	  drawable_offsets (GIMP_DRAWABLE (layer), &doff_x, &doff_y);

	  off_x = (doff_x - x1);
	  off_y = (doff_y - y1);

	  layer_resize (layer, width, height, off_x, off_y);

	  if (layer_is_floating_sel (layer))
	    floating_sel_rigor (layer, TRUE);

	  undo_push_group_end (gimage);
	}
      else
	{
	  floating_layer = gimage_floating_sel (gimage);

	  undo_push_group_start (gimage, CROP_UNDO);

	  /*  relax the floating layer  */
	  if (floating_layer)
	    floating_sel_relax (floating_layer, TRUE);

	  /*  Push the image size to the stack  */
	  undo_push_gimage_mod (gimage);

	  /*  Set the new width and height  */
	  gimage->width = width;
	  gimage->height = height;

	  /*  Resize all channels  */
	  list = gimage->channels;
	  while (list)
	    {
	      channel = (Channel *) list->data;
	      channel_resize (channel, width, height, -x1, -y1);
	      list = g_slist_next (list);
	    }

	  /*  Don't forget the selection mask!  */
	  channel_resize (gimage->selection_mask, width, height, -x1, -y1);
	  gimage_mask_invalidate (gimage);

	  /*  crop all layers  */
	  list = gimage->layers;
	  while (list)
	    {
	      GSList *next;

	      layer = (Layer *) list->data;
	      next = g_slist_next (list);

	      layer_translate (layer, -x1, -y1);

	      drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);

	      if (crop_layers)
		{
		  drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);

		  lx1 = CLAMP (off_x, 0, gimage->width);
		  ly1 = CLAMP (off_y, 0, gimage->height);
		  lx2 = CLAMP ((drawable_width (GIMP_DRAWABLE (layer)) + off_x),
			       0, gimage->width);
		  ly2 = CLAMP ((drawable_height (GIMP_DRAWABLE (layer)) + off_y),
			       0, gimage->height);
!!!-1		  width = lx2 - lx1;
!!!-2		  height = ly2 - ly1;

		  if (width && height)
		    layer_resize (layer, width, height,
				  -(lx1 - off_x),
				  -(ly1 - off_y));
		  else
!!!-3		    gimage_remove_layer (gimage, layer);
		}

	      list = next;
	    }

	  /*  Make sure the projection matches the gimage size  */
	  gimage_projection_realloc (gimage);

	  /*  rigor the floating layer  */
!!!-4	  if (floating_layer)
	    floating_sel_rigor (floating_layer, TRUE);

	  guide_list_ptr = gimage->guides;
	  while ( guide_list_ptr != NULL)
	    {
	      undo_push_guide (gimage, (Guide *)guide_list_ptr->data);
	      guide_list_ptr = guide_list_ptr->next;
	    }
	  undo_push_group_end (gimage);
  
	  /* Adjust any guides we might have laying about */
	  crop_adjust_guides (gimage, x1, y1, x2, y2); 

	  /*  shrink wrap and update all views  */
	  channel_invalidate_previews (gimage);
	  layer_invalidate_previews (gimage);
	  gimage_invalidate_preview (gimage);
	  gdisplays_update_full (gimage);
	  gdisplays_shrink_wrap (gimage);
	}
      gimp_remove_busy_cursors (NULL);
      gdisplays_flush ();
    }
}
Comment 3 Garry R. Osgood 2001-05-20 00:25:05 UTC
[Forgotten addendum]

Apart from the bug, the script does not always seem to be doing what
the author of add-bevel.scm, Andrew Donkin <ard@cs.waiko.ac.nz>
had in mind for his 1.03 version: to add, then trim, a one pixel
perimeter around a layer. His intent is served when a layer's offset
is zero; otherwise he needs to instruct gimp-crop to operate only
on the current layer. This boolean is not being extruded through
to the scheme interface from the underlying core routine crop_image();
so there is no way for Mr. Donkin to request such a thing. 
Fixing this will take a little more work than the dangling pointer
in crop_image().

GRO
Comment 4 Garry R. Osgood 2001-06-02 14:59:45 UTC
1. Seth Burgess, in additional comments to #9350, reported the crash
on floating selections.

2. The mis-cropping cited by dyfa@addict.de in #9350, is related to my
additional comment to this bug made on 19 May 2001.
The scheme interface does not permit a script writer to indicate that
she wishes to crop a layer only, and not the entire image. For layers
smaller than canvases, this miscropping is the general rule.

3. I am testing a partial fix, one that prevents the crash (fixes a
dangling pointer) but does not address the cropping issue. The script
works as the author intended only when the layer size equals the 
canvas size.

*** This bug has been marked as a duplicate of 9350 ***