A89: Re: fwrite bug located (and a bugfix)


[Prev][Next][Index][Thread]

A89: Re: fwrite bug located (and a bugfix)




Many thanks...
and for anyone who wants it, the fixed version of fread

#undef fread // this will cancel old definition from stdio.h
unsigned fread(void *ptr,unsigned size,unsigned n,FILE *f)
{
  unsigned i,j;
  int saveflags=f->flags;
  f->flags|=_F_BIN;
  for(i=0;i<n;i++)
    for(j=0;j<size;j++)
      if((*(unsigned char*)ptr++=fgetc(f))<0) goto exit;
exit:
  f->flags=saveflags;
  return i;
}

Michael Cowart

> 
> Hi!
> 
> After a lot of searching, I finally located where is the bug in
> fwrite. In fact, this is nothing related to a theory given by
> Scott Dial: memory management in fwrite works perfectly. The
> problem is with the sign extension (the most common problem in
> C programming): fwrite will fail on the first byte greater
> than 127. Look this: the line
> 
> if(fnc(*(char*)ptr++,f)<0) goto exit;
> 
> should be:
> 
> if(fnc(*(unsigned char*)ptr++,f)<0) goto exit;
> 
> Why? Suppose that the byte is 255 for example. Then, *(char*)
> will give -1 instead of 255. fnc is the function which returns
> the character intact if there was no error, else returns -1.
> Now, -1 will be stored, and this character will be return
> "intact", i.e. as -1, and the loop will fail...
> 
> In a meantime, until tigcclib 2.2. is released, use corrected
> version of fwrite in your programs:
> 
> #undef fwrite // this will cancel old definition from stdio.h
> unsigned fwrite(void *ptr,unsigned size,unsigned n,FILE *f)
> {
>   unsigned i,j;
>   int saveflags=f->flags;
>   f->flags|=_F_BIN;
>   for(i=0;i<n;i++)
>     for(j=0;j<size;j++)
>       if(fputc(*(unsigned char*)ptr++,f)<0) goto exit;
> exit:
>   f->flags=saveflags;
>   return i;
> }
> 
> Cheers,
> 
> Zeljko Juric
> 
> 
> 



References: