View on GitHub

IRAF Community Distribution

IRAF maintained by the community

Home | Installation | Packages | X11IRAF | PyRAF | Forum ↗

iraf-v216 · Code · Issues (50) · Pull requests (81)

iraf.net pull request #110

Add a trailing \0 to the end of variable format strings in pkg/tbtables/fitsio/

merge olebole merged 1 commit to iraf-community/iraf


olebole commented on 2017-10-26

f2c does not recognize the length of a variable FMT string and will try to read the string until a non-blank appears. For example, the FORTRAN statement

      READ (cval, FMT=iform, ERR=900) val  

translates with f2c to:

    ici__1.icierr = 1;  
    ici__1.iciend = 0;  
    ici__1.icirnum = 1;  
    ici__1.icirlen = cval_len; // <-- length of cval  
    ici__1.iciunit = cval;  
    ici__1.icifmt = iform;     // <-- NO length of iform!  
    i__1 = s_rsfi(&ici__1);  
// [...]  

The format strings are declared as CHARACTER*8 and do not automatically have a \0 appended at the end when they are created. Therefore, when the string is filled with blanks until the end, it will read one char over the end, which is hopefully a non-blank, but also may lead to a segmentation fault. Specifically this happens in unix/f2c/libf2c/fmt.c:

#define skip(s) while(*s==' ') s++  
// [...]  
 static  
#ifdef KR_headers  
char *f_s(s,curloc) char *s;#  
else  
const char *f_s(const char *s, int curloc)  
#endif  
{  
	skip(s);  
	if(*s++!='(')  
	{  
		return(NULL);  
	}  
	if(f__parenlvl++ ==1) f__revloc=curloc;  
	if(op_gen(RET1,curloc,0,0)<0 ||  
		(s=f_list(s))==NULL)  
	{  
		return(NULL);  
	}  
	skip(s); // <------------- here  
	return(s);  
}  

This is probably a bug in f2c; however it is also not fixed in the recent versions as well. To work around this, this PR adds a trailing \0 to the strings used in a FMT statement to mark their end. The maximum length of the generated FMT strings was 7 (in ftc2dd.f), so adding one character will not exceed the declared length.

This is the same as when using the FORMAT statement, where also a null terminated string is used:

1000  FORMAT(I5)  

translates to a simple null terminated C string:

    /* Format strings */  
    static char fmt_1000[] = "(i5)";  

As always, this pull request is successfully tested, with new and old compilers, with Linux and MacOSX, with 32 and 64 bit.


Commits


Last updated on 2017-11-16