[Bf-committers] BUG: File handles closed multiple times (Patch
attached)
Jacques Beaurain
jbeaurain at istop.com
Tue Dec 7 12:31:30 CET 2004
Hi,
I found a minor bug in the image writing functions. The problem was that
the file descriptor in the IMB_saveiff function was closed even one of
the format specific image functions did a fclose on a stream that was
opened on the descriptor. The run-time library documentation has a note
with fclose that states:
"When these functions are used to close a stream, the underlying file
descriptor and OS file handle (or socket) are closed, as well as the
stream. Thus, if the file was originally opened as a file handle or file
descriptor and is closed with *fclose*, do not also call *close* to
close the file descriptor."
The reason I needed to make this fix for my system is that I am trying
the beta of Microsoft Visual Studio 2005 at the moment and that the
updated CRT libraries that ships with it asserts in both the release and
debug versions inside the close call because fclose has already been
closed. This causes crashes every time I try to write an image.
They seem to have added a number of security and stability checks in
various runtime functions. They do this through what they call an
Invalid Parameter Handler routine. The default calls M$'s abort tool
with some information about the invalid parameters (in this cased an
invalid file handle). One can also install a default parameter handler
of ones own to prevent this system from asserting
on every little thing. I do think this is a valid bug though and is not
too sure if bad things like leaks or memory corruptions may happen in
older versions of the CRT or on other platforms.
I will keep you posted on any other things I find.
Cheers,
Jacques
-------------- next part --------------
Index: source/blender/imbuf/intern/IMB_bmp.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/imbuf/intern/IMB_bmp.h,v
retrieving revision 1.8
diff -u -r1.8 IMB_bmp.h
--- source/blender/imbuf/intern/IMB_bmp.h 16 Jul 2004 14:45:06 -0000 1.8
+++ source/blender/imbuf/intern/IMB_bmp.h 7 Dec 2004 11:01:06 -0000
@@ -44,7 +44,7 @@
int imb_is_a_bmp(void *buf);
struct ImBuf *imb_bmp_decode(unsigned char *mem, int size, int flags);
-short imb_savebmp(struct ImBuf *ibuf, int outfile, int flags);
+short imb_savebmp(struct ImBuf *ibuf, int *outfile, int flags);
#endif
Index: source/blender/imbuf/intern/IMB_iris.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/imbuf/intern/IMB_iris.h,v
retrieving revision 1.6
diff -u -r1.6 IMB_iris.h
--- source/blender/imbuf/intern/IMB_iris.h 30 May 2003 01:50:34 -0000 1.6
+++ source/blender/imbuf/intern/IMB_iris.h 7 Dec 2004 11:01:06 -0000
@@ -43,7 +43,7 @@
struct ImBuf;
struct ImBuf *imb_loadiris(unsigned char *mem, int flags);
-short imb_saveiris(struct ImBuf * ibuf, int file, int flags);
+short imb_saveiris(struct ImBuf * ibuf, int *file, int flags);
#endif
Index: source/blender/imbuf/intern/IMB_png.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/imbuf/intern/IMB_png.h,v
retrieving revision 1.7
diff -u -r1.7 IMB_png.h
--- source/blender/imbuf/intern/IMB_png.h 4 Dec 2003 18:18:05 -0000 1.7
+++ source/blender/imbuf/intern/IMB_png.h 7 Dec 2004 11:01:06 -0000
@@ -45,7 +45,7 @@
int imb_is_a_png(void *buf);
struct ImBuf *imb_loadpng(unsigned char *mem, int size, int flags);
-short imb_savepng(struct ImBuf *ibuf, int file, int flags);
+short imb_savepng(struct ImBuf *ibuf, int *file, int flags);
#endif
Index: source/blender/imbuf/intern/IMB_targa.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/imbuf/intern/IMB_targa.h,v
retrieving revision 1.6
diff -u -r1.6 IMB_targa.h
--- source/blender/imbuf/intern/IMB_targa.h 30 May 2003 01:50:34 -0000 1.6
+++ source/blender/imbuf/intern/IMB_targa.h 7 Dec 2004 11:01:06 -0000
@@ -45,7 +45,7 @@
int imb_is_a_targa(void *buf);
struct ImBuf *imb_loadtarga(unsigned char *mem, int flags);
-short imb_savetarga(struct ImBuf * ibuf, int file, int flags);
+short imb_savetarga(struct ImBuf * ibuf, int *file, int flags);
#endif
Index: source/blender/imbuf/intern/bmp.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/imbuf/intern/bmp.c,v
retrieving revision 1.3
diff -u -r1.3 bmp.c
--- source/blender/imbuf/intern/bmp.c 9 Jun 2004 19:49:43 -0000 1.3
+++ source/blender/imbuf/intern/bmp.c 7 Dec 2004 11:01:06 -0000
@@ -199,7 +199,7 @@
}
/* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */
-short imb_savebmp(struct ImBuf *ibuf, int outfile, int flags) {
+short imb_savebmp(struct ImBuf *ibuf, int *outfile, int flags) {
BMPINFOHEADER infoheader;
int bytesize, extrabytes, x, y, t, ptr;
@@ -244,8 +244,10 @@
for (t=0;t<extrabytes;t++) if (putc(0,ofile) == EOF) return 0;
}
if (ofile) {
- fflush(ofile);
+ fflush(ofile);
fclose(ofile);
+ /* The file descriptor needs to be set to -1 if it is closed to prevent the caller from attempting to close again */
+ *outfile = -1;
}
return 1;
}
Index: source/blender/imbuf/intern/iris.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/imbuf/intern/iris.c,v
retrieving revision 1.7
diff -u -r1.7 iris.c
--- source/blender/imbuf/intern/iris.c 30 Mar 2004 14:33:02 -0000 1.7
+++ source/blender/imbuf/intern/iris.c 7 Dec 2004 11:01:06 -0000
@@ -532,7 +532,7 @@
* Added: zbuf write
*/
-static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, int file, int *zptr)
+static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, int *file, int *zptr)
{
FILE *outf;
IMAGE *image;
@@ -612,6 +612,8 @@
free(rlebuf);
free(lumbuf);
fclose(outf);
+ /* The file descriptor needs to be set to -1 if it is closed to prevent the caller from attempting to close again */
+ *file = -1;
if(goodwrite)
return 1;
else {
@@ -690,7 +692,7 @@
return optr - (unsigned char *)rlebuf;
}
-short imb_saveiris(struct ImBuf * ibuf, int file, int flags)
+short imb_saveiris(struct ImBuf * ibuf, int *file, int flags)
{
short zsize;
int ret;
Index: source/blender/imbuf/intern/png.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/imbuf/intern/png.c,v
retrieving revision 1.1
diff -u -r1.1 png.c
--- source/blender/imbuf/intern/png.c 4 Dec 2003 18:18:05 -0000 1.1
+++ source/blender/imbuf/intern/png.c 7 Dec 2004 11:01:06 -0000
@@ -106,7 +106,7 @@
longjmp(png_jmpbuf(png_ptr), 1);
}
-short imb_savepng(struct ImBuf *ibuf, int file, int flags)
+short imb_savepng(struct ImBuf *ibuf, int *file, int flags)
{
png_structp png_ptr;
png_infop info_ptr;
@@ -198,7 +198,7 @@
WriteData,
Flush);
} else {
- fp = fdopen(file, "wb");
+ fp = fdopen(*file, "wb");
png_init_io(png_ptr, fp);
}
@@ -255,6 +255,8 @@
if (fp) {
fflush(fp);
fclose(fp);
+ // The file descriptor needs to be set to -1 if it is closed to prevent the caller from attempting to close again
+ *file = -1;
}
return(1);
Index: source/blender/imbuf/intern/targa.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/imbuf/intern/targa.c,v
retrieving revision 1.7
diff -u -r1.7 targa.c
--- source/blender/imbuf/intern/targa.c 22 Jan 2004 12:59:46 -0000 1.7
+++ source/blender/imbuf/intern/targa.c 7 Dec 2004 11:01:06 -0000
@@ -242,7 +242,7 @@
}
-short imb_savetarga(struct ImBuf * ibuf, int file, int flags)
+short imb_savetarga(struct ImBuf * ibuf, int *file, int flags)
{
char buf[20];
FILE *fildes;
@@ -325,6 +325,8 @@
}
fclose(fildes);
+ /* The file descriptor needs to be set to -1 if it is closed to prevent the caller from attempting to close again */
+ *file = -1;
return (ok);
}
Index: source/blender/imbuf/intern/writeimage.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/imbuf/intern/writeimage.c,v
retrieving revision 1.8
diff -u -r1.8 writeimage.c
--- source/blender/imbuf/intern/writeimage.c 30 Aug 2004 18:43:00 -0000 1.8
+++ source/blender/imbuf/intern/writeimage.c 7 Dec 2004 11:01:06 -0000
@@ -70,12 +70,16 @@
/* Put formats that take a filename here */
if (IS_jpg(ibuf)) {
- if(imb_savejpeg(ibuf, naam, flags)) return (0);
- else return (TRUE);
+ /* The imb_savejpeg function returns TRUE on error */
+ ok = !imb_savejpeg(ibuf, naam, flags);
+ goto cleanup;
}
file = open(naam, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666);
- if (file < 0) return (FALSE);
+ if (file < 0) {
+ ok = FALSE;
+ goto cleanup;
+ }
if (flags & IB_rect){
if (ibuf->cmap){
@@ -85,35 +89,23 @@
/* Put formats that take a filehandle here */
if (IS_png(ibuf)) {
- ok = imb_savepng(ibuf,file,flags);
- if (ok) {
- close (file);
- return (ok);
- }
+ ok = imb_savepng(ibuf,&file,flags);
+ goto cleanup;
}
- if (IS_bmp(ibuf)) {
- ok = imb_savebmp(ibuf,file,flags);
- if (ok) {
- close (file);
- return (ok);
- }
- }
+ if (IS_bmp(ibuf)) {
+ ok = imb_savebmp(ibuf,&file,flags);
+ goto cleanup;
+ }
if (IS_tga(ibuf)) {
- ok = imb_savetarga(ibuf,file,flags);
- if (ok) {
- close (file);
- return (ok);
- }
+ ok = imb_savetarga(ibuf,&file,flags);
+ goto cleanup;
}
if (IS_iris(ibuf)) {
- ok = imb_saveiris(ibuf,file,flags);
- if (ok) {
- close (file);
- return (ok);
- }
+ ok = imb_saveiris(ibuf,&file,flags);
+ goto cleanup;
}
if (ok) ok = imb_start_iff(ibuf,file);
@@ -144,11 +136,14 @@
if (ok) ok = imb_encodebodyh(ibuf,file);
}
if (ok) ok = imb_update_iff(file,BODY);
- }else if (IS_anim(ibuf)) {
+ } else if (IS_anim(ibuf)) {
if (ok) ok = imb_enc_anim(ibuf, file);
if (ok) ok = imb_update_iff(file, BODY);
}
- close(file);
+
+cleanup:
+ if (file!=-1)
+ close(file);
if (ok==FALSE) {
fprintf(stderr,"Couldn't save picture.\n");
More information about the Bf-committers
mailing list