The notorious reader have already noticed that there is a problem with my 
suggested patch. C arrays are zero based so the length to allocate is alen+1.
A modified patch is enclosed.

/Nils

> 
> As I managed to download the source I think I have located the problem. The
> current netCDF reading code maximizes the length of a character attribute 
> to 128 characters. That is not very much if one wants to squeeze in both the
> name of the variables making up a series as well as the value of the series
> position in one global attribute. Further it is incorrect in the sense that
> no check was made that the read of a text attribute actually fitted in the
> space given.
> 
> I made a patch to the getNattr routine in import_ncdf.c that fixes the most
> immediate problem for me. It seems to work fine and I can now read in series
> definition attributes of the length I need.
> 
> There still remains a buffer over-run problem in getattr in the same source 
> file. My suggestion is to fix this in the same way I did the current fix.
> That implies changes in multiple places in the file that I have not yet 
> looked into what effects they will have.
> 
> Anyway, for what it is worth I enclose my suggested patch below.
> 
> Cheers,
> 
> /Nils
> 
> 
> 

*** import_ncdf.c-ORIG	Tue Jul 17 22:37:35 2001
--- import_ncdf.c	Wed Jul 18 11:43:32 2001
***************
*** 531,535 ****
  	  int *deltatime)
  {
!     char stringattr[MAXNAME], *cp, *s[MAXATTRSTR], **lp;
      char *subv[2];
      int ndims, nvars, ngatts, recdim;
--- 531,535 ----
  	  int *deltatime)
  {
!     char stringattr[MAXNAME], *cp, *s[MAXATTRSTR], **lp, *attrtext;
      char *subv[2];
      int ndims, nvars, ngatts, recdim;
***************
*** 563,572 ****
       */
      for (k = 0; k < ngatts; k++) {
!         if(!getNattr(cdfhandle, NC_GLOBAL, k, SERIESATTRIB, 
!                     strlen(SERIESATTRIB), stringattr))
              continue;
  	
  	j = MAXATTRSTR;
! 	cp = parseit(stringattr, &j, s);
  	if(j <= 0) {
  	    DXSetError(ERROR_DATA_INVALID, "bad attribute for series");
--- 563,572 ----
       */
      for (k = 0; k < ngatts; k++) {
!         if(!(attrtext=getNattr(cdfhandle, NC_GLOBAL, k, SERIESATTRIB, 
!                     strlen(SERIESATTRIB), stringattr)))
              continue;
  	
  	j = MAXATTRSTR;
! 	cp = parseit(attrtext, &j, s);
  	if(j <= 0) {
  	    DXSetError(ERROR_DATA_INVALID, "bad attribute for series");
***************
*** 599,603 ****
  	 * vp3 = temp node for finding end of next->next->next chain.
  	 */
! 	if (match_vp(vp, NC_GLOBAL, s, stringattr) != NULL)
  	    continue;
  
--- 599,603 ----
  	 * vp3 = temp node for finding end of next->next->next chain.
  	 */
! 	if (match_vp(vp, NC_GLOBAL, s, attrtext) != NULL)
  	    continue;
  
***************
*** 789,792 ****
--- 789,794 ----
  	}
  	count++;
+ 	DXFree((Pointer) attrtext);
+ 	attrtext=NULL;
      }
  
***************
*** 983,986 ****
--- 985,990 ----
  
    error:
+     if(attrtext)
+       DXFree((Pointer)attrtext);
      if (found)
  	DXFree((Pointer)found);
***************
*** 1420,1423 ****
--- 1424,1430 ----
   *  complete value of the attribute, verify it is a string (char), and 
   *  null terminate it.
+  *  The attribute is returned as a newly allocated string. It is the 
+  *  caller's responsibility the deallocate it when it is no longer 
+  *  needed.
   */
  static char *
***************
*** 1426,1429 ****
--- 1433,1437 ----
      nc_type datatype;
      int i, alen;
+     char *attrtext=NULL;
  
      for(i = n; ; i++) {
***************
*** 1447,1455 ****
      /* does this work?  we are actually using the same buffer for the
       *  input attribute name and for the returned attribute value.
       */
!     ncattget(hand, varid, attrname, stringattr);
!     stringattr[alen] = '\0';
  
!     return stringattr;
  }
  
--- 1455,1466 ----
      /* does this work?  we are actually using the same buffer for the
       *  input attribute name and for the returned attribute value.
+      ncattget(hand, varid, attrname, stringattr);
       */
!     /* No it does not. Make sure the target string has sufficient length */
!     attrtext=DXAllocate(alen+1);
!     ncattget(hand, varid, attrname, attrtext);
!     attrtext[alen] = '\0';
  
!     return attrtext;
  }
  

Reply via email to