It appears as if the list does not distribute e-mails with attachments so my
fix to my import problem does not seem to have gotten through. If it did I
apologize for spamming the list again.

The included patch fixes my problem as well as it correctly reads netCDF
attributes that are longer than the target string. If the attribute is
to long it is truncated and a warning message is printed in the Message
Window.

I think that I use a accompanying DXFree for every DXAllocate that I have
introduced. But someone more knowledgeable than I maybe can have a look at
my suggested changes.

Below is my previous dropped message and the complete patch to import_ncdf.c

/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 13:05:46 2001
***************
*** 183,187 ****
  static Object build_regcon1D(Arrayinfo, int);
  
! static char *getattr(int hand, int varid, char *attrname, char *stringattr);
  static char *getNattr(int hand, int varid, int i, char *attrname, int n, 
                       char *stringattr);
--- 183,188 ----
  static Object build_regcon1D(Arrayinfo, int);
  
! static char *getattr(int hand, int varid, char *attrname, 
!                     char *stringattr,int maxlen);
  static char *getNattr(int hand, int varid, int i, char *attrname, int n, 
                       char *stringattr);
***************
*** 531,535 ****
          int *deltatime)
  {
!     char stringattr[MAXNAME], *cp, *s[MAXATTRSTR], **lp;
      char *subv[2];
      int ndims, nvars, ngatts, recdim;
--- 532,536 ----
          int *deltatime)
  {
!     char stringattr[MAXNAME], *cp, *s[MAXATTRSTR], **lp, *attrtext=NULL;
      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");
--- 564,576 ----
       */
      for (k = 0; k < ngatts; k++) {
!         /* If a continue has been encountered in the previous iteratation */
!         if(attrtext) DXFree((Pointer) attrtext); 
! 
!         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;
  
--- 603,607 ----
         * vp3 = temp node for finding end of next->next->next chain.
         */
!       if (match_vp(vp, NC_GLOBAL, s, attrtext) != NULL)
            continue;
  
***************
*** 789,792 ****
--- 793,802 ----
        }
        count++;
+       DXFree((Pointer) attrtext);
+       attrtext=NULL;
+     }
+     if(attrtext) {
+       DXFree((Pointer) attrtext);
+       attrtext=NULL;
      }
  
***************
*** 796,800 ****
      for(i=0; i<nvars; i++) {
        
!       if(!getattr(cdfhandle, i, FIELDATTRIB, stringattr))
            continue;
  
--- 806,810 ----
      for(i=0; i<nvars; i++) {
        
!       if(!getattr(cdfhandle, i, FIELDATTRIB, stringattr,MAXNAME))
            continue;
  
***************
*** 983,986 ****
--- 993,998 ----
  
    error:
+     if(attrtext)
+       DXFree((Pointer)attrtext);
      if (found)
        DXFree((Pointer)found);
***************
*** 1189,1193 ****
                  return NULL;
          }
!       getattr(vp->cdfid, vp->varid, FIELDATTRIB, stringattr);
            
        cp = stringattr;
--- 1201,1205 ----
                  return NULL;
          }
!       getattr(vp->cdfid, vp->varid, FIELDATTRIB, stringattr,MAXNAME);
            
        cp = stringattr;
***************
*** 1399,1406 ****
   */
  static char *
! getattr(int hand, int varid, char *attrname, char *stringattr)
  {
      nc_type datatype;
      int len;
  
      if(ncattinq(hand, varid, attrname, &datatype, &len) < 0)
--- 1411,1419 ----
   */
  static char *
! getattr(int hand, int varid, char *attrname, char *stringattr,int maxlen)
  {
      nc_type datatype;
      int len;
+     char *tmpattr;
  
      if(ncattinq(hand, varid, attrname, &datatype, &len) < 0)
***************
*** 1410,1416 ****
        return NULL;
  
!     ncattget(hand, varid, attrname, stringattr);
!     stringattr[len] = '\0';
  
      return stringattr;
  }
--- 1423,1438 ----
        return NULL;
  
!     tmpattr=(char *)DXAllocate(len+1);
!     ncattget(hand, varid, attrname, tmpattr);
!     tmpattr[len] = '\0';
! 
!     strncpy(stringattr,tmpattr,maxlen);
!     stringattr[maxlen-1]='\0';
! 
!     if(strncmp(stringattr,tmpattr,maxlen))
!       DXWarning("String attribute truncated: `%s' -> `%s'",
!               tmpattr,stringattr);
  
+     DXFree((Pointer) tmpattr);
      return stringattr;
  }
***************
*** 1420,1423 ****
--- 1442,1448 ----
   *  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 ****
--- 1451,1455 ----
      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;
  }
  
--- 1473,1484 ----
      /* 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;
  }
  
***************
*** 1487,1492 ****
      /* see if there is an 'attribute' attribute on this variable
       */
!     if(!getattr(ap->cdfhandle, ap->varid, ATTRATTRIB, ap->stringattr)
!      && !getattr(ap->cdfhandle, ap->varid, OATTRATTRIB, ap->stringattr))
          goto done;
  
--- 1516,1521 ----
      /* see if there is an 'attribute' attribute on this variable
       */
!     if(!getattr(ap->cdfhandle, ap->varid, ATTRATTRIB, ap->stringattr,MAXNAME)
!      && !getattr(ap->cdfhandle, ap->varid, OATTRATTRIB, 
ap->stringattr,MAXNAME))
          goto done;
  
***************
*** 1675,1679 ****
      /* get the attribute value.
       */
!     if(!getattr(hand, varid, FIELDATTRIB, ap->stringattr))
        return NULL;
      
--- 1704,1708 ----
      /* get the attribute value.
       */
!     if(!getattr(hand, varid, FIELDATTRIB, ap->stringattr,MAXNAME))
        return NULL;
      
***************
*** 1766,1771 ****
       *  doesn't have a 'positions' attribute, assume a regularly spaced grid.
       */
!     if(!getattr(hand, varid, GEOMATTRIB, ap->stringattr)
!     && !getattr(hand, varid, OGEOMATTRIB, ap->stringattr)) {
          nterms = 1;
        indata = build_poscon(ap, I_REGULAR_P, 0);
--- 1795,1800 ----
       *  doesn't have a 'positions' attribute, assume a regularly spaced grid.
       */
!     if(!getattr(hand, varid, GEOMATTRIB, ap->stringattr,MAXNAME)
!     && !getattr(hand, varid, OGEOMATTRIB, ap->stringattr,MAXNAME)) {
          nterms = 1;
        indata = build_poscon(ap, I_REGULAR_P, 0);
***************
*** 1962,1967 ****
       *  which contains the connections information.
       */
!     if(!getattr(hand, varid, TOPOATTRIB, ap->stringattr)
!     && !getattr(hand, varid, OTOPOATTRIB, ap->stringattr)) {
          nterms = 1;
        indata = build_poscon(ap, I_REGULAR_C, 0);
--- 1991,1996 ----
       *  which contains the connections information.
       */
!     if(!getattr(hand, varid, TOPOATTRIB, ap->stringattr,MAXNAME)
!     && !getattr(hand, varid, OTOPOATTRIB, ap->stringattr,MAXNAME)) {
          nterms = 1;
        indata = build_poscon(ap, I_REGULAR_C, 0);
***************
*** 2143,2147 ****
      /* are there additional components that should be added?
       */
!     if(getattr(hand, varid, COMPATTRIB, ap->stringattr)) {
          
        cp = ap->stringattr;
--- 2172,2176 ----
      /* are there additional components that should be added?
       */
!     if(getattr(hand, varid, COMPATTRIB, ap->stringattr,MAXNAME)) {
          
        cp = ap->stringattr;
***************
*** 2324,2328 ****
       *  space for the array, and return with valuelist pointing to it.
       */
!     if(!getattr(ap->cdfhandle, ap->varid, SERIESPOSATTRIB, ap->stringattr))
        return OK;
  
--- 2353,2357 ----
       *  space for the array, and return with valuelist pointing to it.
       */
!     if(!getattr(ap->cdfhandle, ap->varid, SERIESPOSATTRIB, 
ap->stringattr,MAXNAME))
        return OK;
  
***************
*** 2417,2421 ****
      /* get the attribute value.
       */
!     if(getattr(hand, varid, FIELDATTRIB, ap->stringattr)) {
      
        cp = ap->stringattr;
--- 2446,2450 ----
      /* get the attribute value.
       */
!     if(getattr(hand, varid, FIELDATTRIB, ap->stringattr,MAXNAME)) {
      
        cp = ap->stringattr;
***************
*** 2471,2476 ****
       *  doesn't have a 'positions' attribute, assume a regularly spaced grid.
       */
!     if(!getattr(hand, varid, GEOMATTRIB, ap->stringattr)
!     && !getattr(hand, varid, OGEOMATTRIB, ap->stringattr)) {
          i = 1;
          indata = (Array)build_poscon(ap, I_REGULAR_P, 0);
--- 2500,2505 ----
       *  doesn't have a 'positions' attribute, assume a regularly spaced grid.
       */
!     if(!getattr(hand, varid, GEOMATTRIB, ap->stringattr,MAXNAME)
!     && !getattr(hand, varid, OGEOMATTRIB, ap->stringattr,MAXNAME)) {
          i = 1;
          indata = (Array)build_poscon(ap, I_REGULAR_P, 0);
***************
*** 2602,2607 ****
       *  which contains the connections information.
       */
!     if(!getattr(hand, varid, TOPOATTRIB, ap->stringattr)
!     && !getattr(hand, varid, OTOPOATTRIB, ap->stringattr)) {
          i = 1;
          indata = (Array)build_poscon(ap, I_REGULAR_C, 0);
--- 2631,2636 ----
       *  which contains the connections information.
       */
!     if(!getattr(hand, varid, TOPOATTRIB, ap->stringattr,MAXNAME)
!     && !getattr(hand, varid, OTOPOATTRIB, ap->stringattr,MAXNAME)) {
          i = 1;
          indata = (Array)build_poscon(ap, I_REGULAR_C, 0);
***************
*** 2711,2715 ****
      /* are there additional components that should be added?
       */
!     if(getattr(hand, varid, COMPATTRIB, ap->stringattr)) {
          
        cp = ap->stringattr;
--- 2740,2744 ----
      /* are there additional components that should be added?
       */
!     if(getattr(hand, varid, COMPATTRIB, ap->stringattr,MAXNAME)) {
          
        cp = ap->stringattr;

-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   Nils Smeds                        http://www.pdc.kth.se/
   Center for Parallel Computers     e-mail: [EMAIL PROTECTED]
   Royal Institute of Technology     Voice:  +46-8-7909115
   KTH                               Fax:    +46-8-247784 
   S-100 44 Stockholm, Sweden        Office: OB2, room 1546
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   Nils Smeds                        
   HPCSU / Sci & Techn.              e-mail: [EMAIL PROTECTED]
   UNSW, NSW 2052                    Voice:  +61-2-9385 6915
   Sydney                            Fax:    +61-2-9385 ----
   AUSTRALIA                         Office: Red Centre, West, Rm 2075
-----------------------------------------------------------------------

Reply via email to