[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15531] trunk/blender/source/blender/ blenlib/intern/storage.c: Memory leak fix (found with Valgrind)
André Pinto
andresusanopinto at gmail.com
Sat Jul 12 04:36:40 CEST 2008
According to the manpage of getpwuid:
"The return value may point to static area, and may be overwritten by
subsequent calls to getpwent(3), getpwnam(), or getpwuid()."
As so its memory should not be freed... but considering Genscher found
a memory issue with it.. it seems that some implementations may expect
the user to free the memory.. but others return static memory.
The alternative and also thread safe is the function
"int getpwuid_r(uid_t uid, struct passwd *pwbuf, char *buf, size_t
buflen, struct passwd **pwbufp);
Which is available on: _POSIX_C_SOURCE || _XOPEN_SOURCE || _BSD_SOURCE
|| _SVID_SOURCE
I am not sure whether this matches all targets of blender.. but I hope so.
Here is the patch:
Index: source/blender/blenlib/intern/storage.c
===================================================================
--- source/blender/blenlib/intern/storage.c (revision 15531)
+++ source/blender/blenlib/intern/storage.c (working copy)
@@ -42,6 +42,7 @@
#ifndef WIN32
#include <dirent.h>
+#include <errno.h>
#endif
#include <time.h>
@@ -337,6 +338,11 @@
#ifdef WIN32
__int64 st_size;
#else
+ //buffer to getpwuid_r
+ char *buffer = NULL;
+ size_t bufferlen = 1024;
+// long int initlen = sysconf(_SC_GETGR_R_SIZE_MAX);
+
off_t st_size;
#endif
@@ -345,6 +351,10 @@
time_t zero= 0;
file = &files[0];
+
+#ifndef WIN32
+ buffer = (char*)malloc( bufferlen );
+#endif
for(num=0;num<actnum;num++){
#ifdef WIN32
@@ -378,14 +388,33 @@
strcpy(files[num].owner,"user");
#else
{
- struct passwd *pwuser;
- pwuser = getpwuid(files[num].s.st_uid);
- if ( pwuser ) {
- strcpy(files[num].owner, pwuser->pw_name);
- free(pwuser);
- } else {
+ struct passwd result;
+ struct passwd *resultp = NULL;
+
+ while(getpwuid_r(files[num].s.st_uid, &result, buffer, bufferlen,
&resultp) == ERANGE)
+ {
+ char *newbuffer;
+ size_t newlen = 2*bufferlen;
+
+ if(newlen < bufferlen)
+ break; //Overflow
+
+ newbuffer = realloc(buffer, newlen);
+ if(newbuffer == NULL)
+ break; //Out of memory
+
+ buffer = newbuffer;
+ bufferlen = newlen;
+ }
+
+ if(resultp)
+ {
+ strncpy(files[num].owner, resultp->pw_name, sizeof( files[num].owner) );
+ files[num].owner[ sizeof(files[num].owner)-1] = 0;
+ }
+ else
sprintf(files[num].owner, "%d", files[num].s.st_uid);
- }
+
}
#endif
@@ -446,6 +475,12 @@
file++;
}
+
+#ifndef WIN32
+ if(buffer)
+ free(buffer);
+#endif
+
}
unsigned int BLI_getdir(char *dirname, struct direntry **filelist)
More information about the Bf-committers
mailing list