Bug found in ps.select

Justin Hickey jhickey
Thu Jun 5 12:18:36 EDT 1997


Hello all

While trying to get the ps.* commands to work, I came across a bug in the
ps.select command from the src.alpha code (in particular, the ls_painters()
function in $GISBASE/src.alpha/ps.map/ps.select/list.c). The problem was in the
code that generates the list of available postscript painters under the
$GISBASE/etc/paint/ps.devices directory. The code basically does an ls of the
directory and stores the files as a comma separated string. The problem was in
generating the string. I have included the code below:

char *
ls_painters()
{
    char command[1024];
    char *drivers();
    FILE *popen();
    FILE *fp;
    char *list;
    char name[256];
    int len;

    list = NULL;
    len = 0;
    sprintf(command, "ls %s\n", ps_devices(""));
    if (fp = popen (command, "r"))
    {
	while (fscanf (fp, "%s", name) == 1)
	{
	    if (list) strcat(list, ",");
	    len += strlen(name) + 2;
	    list = G_realloc(list, len);
	    strcat(list, name);
	}
    }
    pclose(fp);
    return list;
}

As can be seen inside the while loop, the code gets the next file name,
allocates some memory for it, then concatenates it to the string. This code is
fine except for the first time through the loop. The first time through, "list"
is allocated some memory and now points to whatever is located there.
Unfortunately, "list" is being used as a string and all will be well as long as
the first character at list is the null terminator '\0'. Of course that's not
always the case and when the strcat() function is called, "name" gets appended
to whatever is pointed to by list.

I fixed this bug by simply seting list[0] = '\0' the first time through the
loop. The following is my corrected code:

char *
ls_painters()
{
    char command[1024];
    char *drivers();
    FILE *popen();
    FILE *fp;
    char *list;
    char name[256];
    int len;
    int first = 1; /* added by jhickey */

    list = NULL;
    len = 0;
    sprintf(command, "ls %s\n", ps_devices(""));
    if (fp = popen (command, "r"))
    {
	while (fscanf (fp, "%s", name) == 1)
	{
	    if (list) strcat(list, ",");
	    len += strlen(name) + 2;
	    list = G_realloc(list, len);

	    /* added by jhickey */
	    /* Since list will point somewhere in memory the first time, we
		have to make sure it is an empty string. */
	    if (first)
	    {
		list[0] = '\0';
		first = 0;
	    }
	    /* end of added code */

	    strcat(list, name);
	}
    }
    pclose(fp);
    return list;
}

I don't know if this helps anybody or not, just thought I would put this to the
list in case other people were using the ps.select command. My only question is
whether I should post some sort of notice to the user's list, or should I post
the file to moon incoming and then notify the usr's list?

Any comments?


-- 
Sincerely,

Jazzman (a.k.a. Justin Hickey)  e-mail: jhickey at hpcc.nectec.or.th
High Performance Computing Center
National Electronics and Computer Technology Center (NECTEC)
Bangkok, Thailand
==================================================================
People who think they know everything are very irritating to those
of us who do.  ---Anonymous

Jazz and Trek Rule!!!
==================================================================



More information about the grass-user mailing list