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

> 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.

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???

?

thanks,
Hamish

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@gclements.plus.com>

> > > this bug's URL: http://intevation.de/rt/webrt?serial_num=5037
> > > ---------------------------------------------------------------

..

> 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.

Glynn:

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.

Thanks (again), that's it. Apparently I got this right in do_graph.c
set_last_color() but didn't in do_symbol().

  (fixed in cvs+6.2)

Hamish