On 2013-02-12 20:57:21, Anton Gladky wrote:
> PS I did not upload a new version of the package.
> Waiting for opinions on the patch or a new patch
> from Sebastian, if it will be approved.

Please find attached the new patch. It should be less horrible then
the first, broken patch.

Due to the lack of ICS images, the patch has only been tested with the
ICS images from libics.

Regards
-- 
Sebastian Ramacher
diff --git a/io/readics.cxx b/io/readics.cxx
index 67c57cd..b9a8625 100644
--- a/io/readics.cxx
+++ b/io/readics.cxx
@@ -240,14 +240,12 @@ static int read_ics_header(char *filename,	 /* input filename  */
 **/
 
     int fd, cat;
-    unsigned int length, n_read, ui;
-    char *buffer1, *buffer2, *end;
-    char temp1[100],temp2[100];
+    unsigned int length, ui;
+    char *buffer1;
     int i;
-    char *t, *tg, *bp;
-    char delim1, delim2;
+    char delim1[2] = { '\0' }, delim2[2] = { '\0' };
     static int kwrds = 14;
-    static char *keywrdtable[] =
+    static const char *keywrdtable[] =
     {
       "parameters",
       "order",
@@ -264,40 +262,62 @@ static int read_ics_header(char *filename,	 /* input filename  */
       "byte_order",
       "SCIL_TYPE"
     };
+    /* expected categories of the keywords */
+    static const int expected_category[] = {
+      1, 1, 1, 1, 1,
+      2, 2, 2,
+      3, 3, 3, 3,
+      2, 2
+    };
 
     /* make the proper filename and open the ICS file */
-    strcpy(temp1,filename);
-    strcat(temp1,".ics");
-    if ((fd = open(temp1,O_RDONLY)) < 0) return(-2);
+    char* path = NULL;
+    if (asprintf(&path, "%s.ics", filename) == -1) {
+      return -1;
+    }
+
+    fd = open(path,O_RDONLY);
+    free(path);
+    if (fd < 0) {
+      return(-2);
+    }
 
     /* get the length of the ICS file and rewind */
     length = (unsigned int)lseek(fd,0L,2);
     lseek(fd,0L,0);
 
+    /* the first two characters are the seperators */
+    if (length < 2)
+    {
+      close(fd);
+      return -4;
+    }
+
     /* allocate space for all data from the ICS file */
-    if ((buffer1 = (char *)malloc(length)) == NULL)
+    if ((buffer1 = (char *)malloc(length - 1)) == NULL)
     {
       close(fd);
       return(-1);
     }
 
-    /* allocate space for the unresolved data from the ICS file */
-    if ((buffer2 = (char *)malloc(length)) == NULL)
+    /* read delimiters */
+    if (read(fd, delim1, 1) != 1 || read(fd, delim2, 1) != 1)
     {
       close(fd);
       free(buffer1);
-	return(-1);
+      return(-3);
     }
 
+    length -= 2;
     /* read the data into buffer1 and close the file */
-    if ((n_read = read(fd,buffer1,length)) != length)
+    if (read(fd,buffer1,length) != length)
     {
       close(fd);
       free(buffer1);
-	free(buffer2);
       return(-3);
     }
     close(fd);
+    buffer1[length] = '\0';
 
     /* initialisations */
     icsheader->valid_filename = FALSE;
@@ -315,391 +335,277 @@ static int read_ics_header(char *filename,	 /* input filename  */
     icsheader->valid_compression = FALSE;
     icsheader->valid_byteorder = FALSE;
     icsheader->valid_SCIL_TYPE = FALSE;
-    bp = buffer1;
-    end = bp + length;	/* EOF */
-    *buffer2 = '\0';	/* initially empty */
-    delim1 = *bp++;	/* field delimiter */
-    delim2 = *bp++;	/* record delimiter */
-    t = temp1;
 
     /* check if written by ICS */
-    while (*bp != delim2)
-	*t++ = *bp++;
-    bp++;
-    *t = '\0';
-    if (strncmp(temp1,"ICS",3) && strncmp(temp1,"ics",3))
+    char* record_saveptr = NULL;
+    char* record = strtok_r(buffer1, delim2, &record_saveptr);
+    if (record == NULL)
+    {
+      free(buffer1);
+      return -4;
+    }
+
+    if (strncmp(record,"ICS",3) && strncmp(record,"ics",3))
     {
       free(buffer1);
-	free(buffer2);
       return(-4);
     }
 
     /* get the filename from the ICS file */
+    record = strtok_r(NULL, delim2, &record_saveptr);
+    if (record == NULL)
+    {
+      free(buffer1);
+      return -4;
+    }
 
-    t = temp1;
-    while (*bp != delim2)
-	*t++ = *bp++;
-    bp++;
-    *t = '\0';
-
-    t = strchr(temp1,delim1);
-    strcpy(icsheader->filename,t);
-    *t = '\0';
-
-    if (strcmp(temp1,"filename"))
+    char* field_saveptr = NULL;
+    char* field = strtok_r(record, delim1, &field_saveptr);
+    if (strcmp(field, "filename"))
     {
       free(buffer1);
-	free(buffer2);
       return(-5);
     }
+
+    field = strtok_r(NULL, delim1, &field_saveptr);
+    if (field == NULL)
+    {
+      free(buffer1);
+      return -4;
+    }
+
+    strncpy(icsheader->filename, field, FILENAME_SIZE);
+    icsheader->filename[FILENAME_SIZE - 1] = '\0';
     icsheader->valid_filename = TRUE;
 
     /* check the following records one by one and try to resolve
        the information per record */
-    while (bp < end)	/* until EOF */
+    while ((record = strtok_r(NULL, delim2, &record_saveptr)) != NULL)
     {
-	/* get the next record into temp1 */
-	t = temp1;
-	while (*bp != delim2 && bp < end)	/* dont read beyond EOF */
-	    *t++ = *bp++;
-	bp++;
-	*t = '\0';
-      
-      /* get the category into temp2 */
-	t = temp1;
-	tg = temp2;
-	while (*t != delim1)
-	    *tg++ = *t++;
-	t++;
-	*tg = '\0';
+      field_saveptr = NULL;
+      /* get the category */
+      field = strtok_r(record, delim1, &field_saveptr);
+      if (field == NULL)
+      {
+        free(buffer1);
+        return -4;
+      }
 
       /* check if it is one of the decodable categories */
       cat = 0;
-	if (!strcmp(temp2,"layout")) cat = 1;
-	if (!strcmp(temp2,"representation")) cat = 2;
-	if (!strcmp(temp2,"parameter")) cat = 3;
-
+      if (!strcmp(field, "layout")) cat = 1;
+      else if (!strcmp(field, "representation")) cat = 2;
+      else if (!strcmp(field, "parameter")) cat = 3;
       if (cat == 0)
-	{
-	    /* if not concatenate record to buffer2 */
-	    strcat(buffer2,temp1);
-	    strcat(buffer2,"\n");
+        /* if not, ignore it */
         continue;
-	}
+
       /* get the next field from this record */
-	tg = temp2;
-	while (*t != delim1)
-	    *tg++ = *t++;
-	t++;
-	*tg = '\0';
+      field = strtok_r(NULL, delim1, &field_saveptr);
+      if (field == NULL)
+      {
+        free(buffer1);
+        return -4;
+      }
 
       /* find this item in the keyword table */
       for (i = 0; i < kwrds; i++)
-	    if (!strcmp(temp2,keywrdtable[i])) break;
+        if (!strcmp(field, keywrdtable[i]))
+          break;
+
       if (i == kwrds)
-	{ /* not found in the keyword table */
-	    /* concatenate this record to buffer2 */
-	    strcat(buffer2,temp1);
-	    strcat(buffer2,"\n");
+        /* not found in the keyword table, ignore it */
+        continue;
+      if (cat != expected_category[i])
+        /* wrong category, continue */
         continue;
-	}
 
+      /* handle values */
+      field = strtok_r(NULL, delim1, &field_saveptr);
+      if (field == NULL)
+      {
+        free(buffer1);
+        return -4;
+      }
       /* switch to the right value handling routine */
       switch (i)
       {
         case 0: /* parameters */
-	    if (cat != 1)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
-	    tg = temp2;
-	    while (*t != '\0')
-		*tg++ = *t++;
-	    *tg = '\0';
-	    t++;
-	    icsheader->parameters = atoi(temp2);
+          icsheader->parameters = atoi(field);
           if (icsheader->parameters > MAXDIM)
           {  /* if necessary change MAXDIM in ics.h */
             free(buffer1);
-		free(buffer2);
             return(-6);
           }
           icsheader->valid_parameters = TRUE;
           break;
         case 1: /* order */
-	    if (cat != 1)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
           if (icsheader->parameters == 0)
           { /* need to know the number of parameters first */
             free(buffer1);
-		free(buffer2);
             return(-5);
           }
           for (i = 0; i < icsheader->parameters; i++)
           {
-		tg = temp2;
-		while (*t != delim1 && *t != '\0')
-		    *tg++ = *t++;
-		*tg = '\0';
-		t++;
-		strcpy(icsheader->order[i],temp2);
+            if (field == NULL)
+            {
+              /* not enough paramaters */
+              free(buffer1);
+              return -4;
+            }
+            strncpy(icsheader->order[i], field, ORDER_SIZE);
+            icsheader->order[i][ORDER_SIZE - 1] = '\0';
+            field = strtok_r(NULL, delim1, &field_saveptr);
           }
           icsheader->valid_order = TRUE;
           break;
         case 2: /* sizes */
-	    if (cat != 1)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
           if (icsheader->parameters == 0)
           { /* need to know the number of parameters first */
             free(buffer1);
-		free(buffer2);
             return(-5);
           }
           for (i = 0; i < icsheader->parameters; i++)
           {
-		tg = temp2;
-		while (*t != delim1 && *t != '\0')
-		    *tg++ = *t++;
-		*tg = '\0';
-		t++;
-		icsheader->sizes[i] = atoi(temp2);
+            if (field == NULL) {
+              /* not enough paramaters */
+              free(buffer1);
+              return -4;
+            }
+            icsheader->sizes[i] = atoi(field);
+            field = strtok_r(NULL, delim1, &field_saveptr);
           }
           icsheader->valid_sizes = TRUE;
           break;
         case 3: /* coord */
-	    if (cat != 1)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
-	    tg = temp2;
-	    while (*t != '\0')
-		*tg++ = *t++;
-	    *tg = '\0';
-	    t++;
-	    strcpy(icsheader->coord,temp2);
+          strncpy(icsheader->coord, field, COORD_SIZE);
+          icsheader->coord[COORD_SIZE - 1] = '\0';
           icsheader->valid_coord = TRUE;
           break;
         case 4: /* significant bits */
-	    if (cat != 1)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
-	    tg = temp2;
-	    while (*t != '\0')
-		*tg++ = *t++;
-	    *tg = '\0';
-	    t++;
-	    icsheader->sigbits = atoi(temp2);
+          icsheader->sigbits = atoi(field);
           icsheader->valid_sigbits = TRUE;
           break;
         case 5: /* format */
-	    if (cat != 2)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
-	    tg = temp2;
-	    while (*t != '\0')
-		*tg++ = *t++;
-	    *tg = '\0';
-	    t++;
-	    strcpy(icsheader->format,temp2);
+          strncpy(icsheader->format, field, FORMAT_SIZE);
+          icsheader->format[FORMAT_SIZE - 1] = '\0';
           icsheader->valid_format = TRUE;
           break;
         case 6: /* signed or unsigned */
-	    if (cat != 2)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
-	    tg = temp2;
-	    while (*t != '\0')
-		*tg++ = *t++;
-	    *tg = '\0';
-	    t++;
-	    if (!strcmp(temp2,"unsigned"))
+          if (!strcmp(field, "unsigned"))
             icsheader->sign = UNSIGNED;
-	    else icsheader->sign = SIGNED;
+          else
+            icsheader->sign = SIGNED;
           icsheader->valid_sign = TRUE;
           break;
         case 7: /* packing */
-	    if (cat != 2)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
-	    tg = temp2;
-	    while (*t != '\0')
-		*tg++ = *t++;
-	    *tg = '\0';
-	    t++;
-	    strcpy(icsheader->compression,temp2);
+          strncpy(icsheader->compression, field, CMPS_SIZE);
+          icsheader->compression[CMPS_SIZE - 1] = '\0';
           icsheader->valid_compression = TRUE;
           break;
         case 8: /* origin */
-	    if (cat != 3)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
           if (icsheader->parameters == 0)
           { /* need to know the number of parameters first */
             free(buffer1);
-		free(buffer2);
             return(-5);
           }
           for (i = 0; i < icsheader->parameters; i++)
           {
-		tg = temp2;
-		while (*t != delim1 && *t != '\0')
-		    *tg++ = *t++;
-		*tg = '\0';
-		t++;
-		icsheader->origin[i] = (float)atof(temp2);
+            if (field == NULL) {
+              /* not enough paramaters */
+              free(buffer1);
+              return -4;
+            }
+            icsheader->origin[i] = (float)atof(field);
+            field = strtok_r(NULL, delim1, &field_saveptr);
           }
           icsheader->valid_origin = TRUE;
           break;
         case 9: /* scale */
-	    if (cat != 3)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
           if (icsheader->parameters == 0)
           { /* need to know the number of parameters first */
             free(buffer1);
-		free(buffer2);
             return(-5);
           }
           for (i = 0; i < icsheader->parameters; i++)
           {
-		tg = temp2;
-		while (*t != delim1 && *t != '\0')
-		    *tg++ = *t++;
-		*tg = '\0';
-		t++;
-		icsheader->scale[i] = (float)atof(temp2);
+            if (field == NULL) {
+              /* not enough paramaters */
+              free(buffer1);
+              return -4;
+            }
+            icsheader->scale[i] = (float)atof(field);
+            field = strtok_r(NULL, delim1, &field_saveptr);
           }
           icsheader->valid_scale = TRUE;
           break;
         case 10: /* labels */
-	    if (cat != 3)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
           if (icsheader->parameters == 0)
           { /* need to know the number of parameters first */
             free(buffer1);
-		free(buffer2);
             return(-5);
           }
           for (i = 0; i < icsheader->parameters; i++)
           {
-		tg = temp2;
-		while (*t != delim1 && *t != '\0')
-		    *tg++ = *t++;
-		*tg = '\0';
-		t++;
-		strcpy(icsheader->label[i],temp2);
+            if (field == NULL) {
+              /* not enough paramaters */
+              free(buffer1);
+              return -4;
+            }
+            strncpy(icsheader->label[i], field, LABEL_SIZE);
+            icsheader->label[i][LABEL_SIZE - 1] = '\0';
+            field = strtok_r(NULL, delim1, &field_saveptr);
           }
           icsheader->valid_label = TRUE;
           break;
         case 11: /* units */
-	    if (cat != 3)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
           if (icsheader->parameters == 0)
           { /* need to know the number of parameters first */
             free(buffer1);
-		free(buffer2);
             return(-5);
           }
           for (i = 0; i < icsheader->parameters; i++)
           {
-		tg = temp2;
-		while (*t != delim1 && *t != '\0')
-		    *tg++ = *t++;
-		*tg = '\0';
-		t++;
-		strcpy(icsheader->units[i],temp2);
+            if (field == NULL) {
+              /* not enough paramaters */
+              free(buffer1);
+              return -4;
+            }
+            strncpy(icsheader->units[i], field, UNITS_SIZE);
+            icsheader->units[i][UNITS_SIZE - 1] = '\0';
+            field = strtok_r(NULL, delim1, &field_saveptr);
           }
           icsheader->valid_units = TRUE;
           break;
         case 12: /* byteorder */
-	    if (cat != 2)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
-	    if (icsheader->sizes[0] == 0)
-	    { /* need to know the number of bits first */
+          if (icsheader->parameters == 0)
+          { /* need to know the number of parameters first */
             free(buffer1);
-		free(buffer2);
             return(-5);
           }
           length = icsheader->sizes[0] / 8;
           for (ui = 0; ui < length; ui++)
           {
-		tg = temp2;
-		while (*t != delim1 && *t != '\0')
-		    *tg++ = *t++;
-		*tg = '\0';
-		t++;
-		icsheader->byteorder[ui] = atoi(temp2);
+            if (field == NULL) {
+              /* not enough paramaters */
+              free(buffer1);
+              return -4;
+            }
+            icsheader->byteorder[ui] = atoi(field);
+            field = strtok_r(NULL, delim1, &field_saveptr);
           }
           icsheader->valid_byteorder = TRUE;
           break;
         case 13: /* SCIL_TYPE */
-	    if (cat != 2)
-	    { /* wrong category concatenate this record to buffer2 */
-		strcat(buffer2,temp1);
-		strcat(buffer2,"\n");
-		break;
-	    }
-	    tg = temp2;
-	    while (*t != '\0')
-		*tg++ = *t++;
-	    *tg = '\0';
-	    t++;
-	    strcpy(icsheader->SCIL_TYPE,temp2);
+          strncpy(icsheader->SCIL_TYPE, field, SCIL_SIZE);
+          icsheader->SCIL_TYPE[SCIL_SIZE - 1] = '\0';
           icsheader->valid_SCIL_TYPE = TRUE;
           break;
-	  default:
-	    /* unknown category concatenate this record to buffer2 */
-	    strcat(buffer2,temp1);
-	    strcat(buffer2,"\n");
-	    break;
       }
     }
 
     /* clean up and return */
     free(buffer1);
-    free(buffer2);
     return(0);
 }
 

Attachment: signature.asc
Description: Digital signature

Reply via email to