[GRASS-dev] [bug #5037] (grass) GRASS 6.3: d.graph

Glynn Clements glynn at gclements.plus.com
Thu Sep 14 02:38:38 EDT 2006


Hamish wrote:

> > > this bug's URL: http://intevation.de/rt/webrt?serial_num=5037
> > > -------------------------------------------------------------------
> > > 
> > > Subject: GRASS 6.3: d.graph segfault
> > > 
> > > d.graph segfaults on startup. (GRASS 6.3-cvs only)
> ..
> Glynn:
> > It segfaults because trans is NULL, because R_RGB_color()
> > is called before R_open_driver().
> > 
> > R_open_driver() or R__open_quiet() must be called before almost any
> > other R_* functions are called. The only exceptions are:
> >
> > 	R_parse_monitorcap
> > 	R_set_update_function
> > 	R_call_update_function
> > 	R_has_update_function
> > 	R_set_cancel
> > 	R_get_cancel
> > 	R_pad_freelist
> > 	R_pad_perror
> > 
> > The old library would silently ignore any operations performed while
> > not connected to a driver.
> 
> 
> There's another problem, G_str_to_color() [lib/gis/color_str.c] returns
> an error if a color is given as a R:G:B triplet.

Same program, but a completely unrelated bug.

> It seems to work fine with triplets from other modules (d.vect).
> 
> e.g.:
> 
> G63> echo "symbol basic/box 16 50 50 green 50:50:50" | d.graph
> WARNING: [50:50:50]: No such color
> 
> 
> sscanf() fills red,green,blue with garbage? [which fails >255 test]
> 
>     ret = sscanf (buf, "%d%[,:; ]%d%[,:; ]%d", red, temp, green, temp, blue);
> 
> 
> I'm having no luck debugging this. R,G,B getting cast to another type
> somehwhere????

lib/gis/color_str.c:54:

	int G_str_to_color (const char *str, int *red, int *green, int *blue)

include/gis.h:299:

	typedef struct
	{
	    unsigned char r, g, b, a;  /* red, green, blue, and alpha */
	} RGBA_Color ;

display/d.graph/do_graph.c:386:

	    ret = G_str_to_color(line_color_str, &line_color->r, &line_color->g, &line_color->b);

IOW, do_graph.c is passing pointers to "unsigned char" fields while
G_str_to_color() expects pointers to "int"s, resulting in the pointer
targets overlapping (each is 4 bytes wide, but they start 1 byte
apart). The value of *red will be the result of reading the entire
structure as if it was an int.

On a little-endian system, the value will be 0xAABBGGRR (the alpha
field will typically contain garbage); on a big-endian system, it
would be 0xRRGGBBAA. However, the most common big-endian architecture
(PPC) requires "int"s to be aligned, so you would get an exception
(SIGBUS, IIRC) trying to read or write *green or *blue.

The d.graph code needs to be changed to e.g:

	{
	    int r, g, b;
	    ret = G_str_to_color(line_color_str, &r, &g, &b);
	    line_color->r = (unsigned char) r;
	    line_color->g = (unsigned char) g;
	    line_color->b = (unsigned char) b;
	}

-- 
Glynn Clements <glynn at gclements.plus.com>




More information about the grass-dev mailing list