X-Authentication-Warning: delorie.com: mailnull set sender to djgpp-workers-bounces using -f Sender: rich AT phekda DOT freeserve DOT co DOT uk Message-ID: <3C36F39E.D32EDD38@phekda.freeserve.co.uk> Date: Sat, 05 Jan 2002 12:37:50 +0000 From: Richard Dawe X-Mailer: Mozilla 4.77 [en] (X11; U; Linux 2.2.19 i586) X-Accept-Language: de,fr MIME-Version: 1.0 To: djgpp-workers AT delorie DOT com Subject: Re: Memory leaks fixes References: <319B464B DOT 652FB9D9 DOT 09ACFA57 AT netscape DOT net> <3C3218C0 DOT 9F9BC198 AT phekda DOT freeserve DOT co DOT uk> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com Hello. Please find below a diff that fixes a couple of realloc memory leaks in: src/libc/fsext/fsext.c src/libc/posix/glob/glob.c src/libc/posix/regex/regcomp.c I've updated Alexander Aganichev's patch to fix the things I thought were wrong with his patch to fsext.c. I also fixed a leak in regcomp(). I also fixed the following files, which weren't handling malloc() or realloc() failures particularly well: src/libm/math/chew.c src/stub/djasm.y - also use EXIT_* instead of 0, 1 src/debug/common/dbgredir.c src/debug/edebug/unassmbl.c src/debug/fsdb/unassmbl.c src/makemake.c src/mkdoc/mkdoc.cc src/utils/texi2ps/ifset.c - also use EXIT_* instead of 0, 1 zoneinfo/src/strftime.c tests/libclink/objs.cc tests/libclink/slist.cc There were also some small changes to: src/utils/texi2ps/texi2ps.c - exit codes - use EXIT_* src/docs/kb/wc204.txi - what's changed Now, to testing: I guess I should trying using a bash rebuilt with CVS, to check that the fixes to glob() and regcomp() haven't broken anything. Any suggestions on other ways to test them would be appreciated. The debuggers seem to behave the same way as stock 2.03, at least in a small test with a zippo debugging binary using 'whereis' in edebug32 or ALT+W in fsdb. makemake and mkdoc still work. The debuggers built with the modified djasm still work. libclink's check still works. Any comments appreciated. Thanks, bye, Rich =] -- Richard Dawe [ http://www.phekda.freeserve.co.uk/richdawe/ ] Index: src/libc/fsext/fsext.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/fsext/fsext.c,v retrieving revision 1.3 diff -p -u -3 -r1.3 fsext.c --- src/libc/fsext/fsext.c 2000/06/29 08:37:09 1.3 +++ src/libc/fsext/fsext.c 2002/01/05 12:27:35 @@ -1,3 +1,4 @@ +/* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ @@ -88,11 +89,19 @@ grow_table(int _fd) if (num_fds <= _fd) { + __FSEXT_entry *temp; int old_fds = num_fds, i; + num_fds = (_fd+256) & ~255; - fsext_list = (__FSEXT_entry *)realloc(fsext_list, num_fds * sizeof(__FSEXT_entry)); - if (fsext_list == 0) + temp = (__FSEXT_entry *)realloc(fsext_list, num_fds * sizeof(__FSEXT_entry)); + if (temp == 0) + { + /* Keep the current fsext_list, so that we can tidy the FSEXTs + up properly. */ + num_fds = old_fds; return 1; + } + fsext_list = temp; for (i=old_fds; igl_pathv = (char **)realloc(_pglob->gl_pathv, (l_ofs + _pglob->gl_pathc + save_count + 1) * sizeof(char *)); - if (_pglob->gl_pathv == 0) + char **temp = (char **)realloc(_pglob->gl_pathv, (l_ofs + _pglob->gl_pathc + save_count + 1) * sizeof(char *)); + if (temp == 0) + { + free(_pglob->gl_pathv); + _pglob->gl_pathv = NULL; return GLOB_NOSPACE; + } + _pglob->gl_pathv = temp; l_ptr = l_ofs + _pglob->gl_pathc; } else Index: src/libc/posix/regex/regcomp.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/regex/regcomp.c,v retrieving revision 1.5 diff -p -u -3 -r1.5 regcomp.c --- src/libc/posix/regex/regcomp.c 2001/06/09 20:50:55 1.5 +++ src/libc/posix/regex/regcomp.c 2002/01/05 12:27:40 @@ -1,3 +1,4 @@ +/* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ #include @@ -1014,14 +1015,24 @@ register struct parse *p; nbytes = nc / CHAR_BIT * css; if (p->g->sets == NULL) p->g->sets = (cset *)malloc(nc * sizeof(cset)); - else - p->g->sets = (cset *)realloc((char *)p->g->sets, + else { + cset *temp = (cset *)realloc((char *)p->g->sets, nc * sizeof(cset)); + /* Don't leak memory if realloc() fails. */ + if (temp == NULL) + free(p->g->sets); + p->g->sets = temp; + } if (p->g->setbits == NULL) p->g->setbits = (uch *)malloc(nbytes); else { - p->g->setbits = (uch *)realloc((char *)p->g->setbits, - nbytes); + uch *temp = (uch *)realloc((char *)p->g->setbits, + nbytes); + /* Don't leak memory if realloc() fails. */ + if (temp == NULL) + free(p->g->setbits); + p->g->setbits = temp; + /* xxx this isn't right if setbits is now NULL */ for (i = 0; i < no; i++) p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT); Index: src/libm/math/chew.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libm/math/chew.c,v retrieving revision 1.1 diff -p -u -3 -r1.1 chew.c --- src/libm/math/chew.c 1998/07/06 15:17:48 1.1 +++ src/libm/math/chew.c 2002/01/05 12:27:43 @@ -37,6 +37,7 @@ There is no #include "ansidecl.h" #include +#include #include #include #include @@ -141,6 +142,12 @@ static void DEFUN(catchar,(buffer, ch), { buffer->size *=2; buffer->ptr = realloc(buffer->ptr, buffer->size); + if (buffer->ptr == NULL) + { + fprintf(stderr, "Error: Unable to reallocate memory at %s:%d\n", + __FILE__, __LINE__); + exit(EXIT_FAILURE); + } } buffer->ptr[buffer->write_idx ++ ] = ch; @@ -1225,6 +1232,12 @@ DEFUN(add_to_definition,(entry, word), entry->code = (stinst_type *) realloc((char *)(entry->code), entry->code_length *sizeof(word_type)); + if (entry->code == NULL) + { + fprintf(stderr, "Error: Unable to reallocate memory at %s:%d\n", + __FILE__, __LINE__); + exit(EXIT_FAILURE); + } } entry->code[entry->code_end] = word; Index: src/stub/djasm.y =================================================================== RCS file: /cvs/djgpp/djgpp/src/stub/djasm.y,v retrieving revision 1.12 diff -p -u -3 -r1.12 djasm.y --- src/stub/djasm.y 2001/06/20 20:35:20 1.12 +++ src/stub/djasm.y 2002/01/05 12:27:55 @@ -1,3 +1,4 @@ +/* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ @@ -1335,6 +1336,13 @@ FileStack *file_stack = 0; FILE *infile; FILE *outfile; +void memory_failure (const char *file, const int line) +{ + fprintf(stderr, "Error: Unable to allocate memory at %s:%d\n", + __FILE__, __LINE__); + exit(EXIT_FAILURE); +} + int scmp_a(void const *a, void const *b) { return strcmp((*(Symbol **)a)->name, (*(Symbol **)b)->name); @@ -1372,7 +1380,7 @@ int main(int argc, char **argv) if (argc < 2) { fprintf(stderr,"usage: djasm infile [outfile] [mapfile]\n"); - exit(1); + exit(EXIT_FAILURE); } inname = argv[1]; infile = fopen(argv[1], "r"); @@ -1380,7 +1388,7 @@ int main(int argc, char **argv) { fprintf(stderr, "Error: cannot open file %s for reading\n", argv[1]); perror("The error was"); - exit(1); + exit(EXIT_FAILURE); } yyparse(); fclose(infile); @@ -1461,6 +1469,8 @@ int main(int argc, char **argv) { char *dot=0, *sl=0, *cp; outfilename = (char *)malloc(strlen(argv[1])+5); + if (outfilename == NULL) + memory_failure(__FILE__, __LINE__); strcpy(outfilename, argv[1]); for (cp=outfilename; *cp; cp++) { @@ -1496,6 +1506,8 @@ int main(int argc, char **argv) if (!dot) { sl = (char *)malloc(strlen(outfilename)+5); + if (sl == NULL) + memory_failure(__FILE__, __LINE__); strcpy(sl, outfilename); outfilename = sl; dot = outfilename + strlen(outfilename); @@ -1525,7 +1537,7 @@ int main(int argc, char **argv) { fprintf(stderr, "Error: cannot open file %s for writing\n", outfilename); perror("The error was"); - exit(1); + exit(EXIT_FAILURE); } switch (out_type) @@ -1698,9 +1710,13 @@ Symbol *get_symbol(char *name, int creat if (!create) return 0; s = (Symbol *)malloc(sizeof(Symbol)); + if (s == NULL) + memory_failure(__FILE__, __LINE__); s->next = symtab; symtab = s; s->name = (char *)malloc(strlen(name)+1); + if (s->name == NULL) + memory_failure(__FILE__, __LINE__); strcpy(s->name, name); s->value = 0; s->defined = 0; @@ -1992,6 +2008,8 @@ void sortsyms(int (*sortf)(void const *, for (s=symtab, ns=0; s; s=s->next) ns ++; st = (Symbol **)malloc(sizeof(Symbol *) * ns); + if (st == NULL) + memory_failure(__FILE__, __LINE__); for (s=symtab, ns=0; s; s=s->next, ns++) st[ns] = s; qsort(st, ns, sizeof(Symbol *), sortf); @@ -2008,6 +2026,8 @@ void emit(void *ptr, int len) { outsize += 512; outbin = realloc(outbin, outsize); + if (outbin == NULL) + memory_failure(__FILE__, __LINE__); } set_lineaddr(); memcpy(outbin+pc, ptr, len); @@ -2069,6 +2089,8 @@ void emits(Symbol *s, int offset, int re return; } p = (Patch *)malloc(sizeof(Patch)); + if (p == NULL) + memory_failure(__FILE__, __LINE__); p->next = s->patches; s->patches = p; p->location = pc; @@ -2218,6 +2240,8 @@ void reg(int which) { Patch *p; p = (Patch *)malloc(sizeof(Patch)); + if (p == NULL) + memory_failure(__FILE__, __LINE__); p->next = s->patches; s->patches = p; p->location = pc+1+needsib; /* ALL bytes emitted below, accounts for yet to be emitted mbyte */ @@ -2600,6 +2624,9 @@ void set_lineaddr() lineaddr = (lineaddr_s *)realloc(lineaddr, max_lineaddr * sizeof(lineaddr_s)); else lineaddr = (lineaddr_s *)malloc(max_lineaddr * sizeof(lineaddr_s)); + + if (lineaddr == NULL) + memory_failure(__FILE__, __LINE__); } lineaddr[num_lineaddr].line = lineno; lineaddr[num_lineaddr].addr = pc; @@ -2621,10 +2648,14 @@ void add_copyright(char *buf) if (copyright == 0) { copyright = (char *)malloc(strlen(buf)+1); + if (copyright == NULL) + memory_failure(__FILE__, __LINE__); strcpy(copyright, buf); return; } tmp = (char *)malloc(strlen(copyright) + strlen(buf) + 3); + if (tmp == NULL) + memory_failure(__FILE__, __LINE__); strcpy(tmp, copyright); strcat(tmp, "\r\n"); strcat(tmp, buf); @@ -2685,7 +2716,7 @@ void set_image_type(char *t) if (pc) { fprintf(stderr, "Cannot make com file without .type \"com\"\n"); - exit(1); + exit(EXIT_FAILURE); } while (pc < 0x100) emitb(0x90); @@ -2710,6 +2741,8 @@ void do_include(char *fname) return; } fs = (FileStack *)malloc(sizeof(FileStack)); + if (fs == NULL) + memory_failure(__FILE__, __LINE__); fs->line = lineno; fs->prev = file_stack; fs->f = infile; @@ -2718,6 +2751,8 @@ void do_include(char *fname) infile = f; inname = (char *)malloc(strlen(fname)+1); + if (inname == NULL) + memory_failure(__FILE__, __LINE__); strcpy(inname, fname); lineno = 1; } @@ -2882,6 +2917,8 @@ void do_linkcoff (char *filename) if (!s->defined) { Patch *pat = (Patch *) malloc (sizeof (Patch)); + if (pat == NULL) + memory_failure(__FILE__, __LINE__); if (rp->r_type == RELOC_REL32) fprintf (stderr,"%s:%d: warning:" Index: src/debug/common/dbgredir.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/debug/common/dbgredir.c,v retrieving revision 1.3 diff -p -u -3 -r1.3 dbgredir.c --- src/debug/common/dbgredir.c 1999/06/14 16:20:41 1.3 +++ src/debug/common/dbgredir.c 2002/01/05 12:27:57 @@ -452,8 +452,10 @@ redir_cmdline_parse (const char *args, c } } *d = '\0'; - /* Free unused space. */ - cmd->command = (char *) realloc (cmd->command, cmd_len + 1); + /* Free unused space, if we can. */ + d = (char *) realloc (cmd->command, cmd_len + 1); + if (d) + cmd->command = d; return 0; } Index: src/debug/edebug/unassmbl.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/debug/edebug/unassmbl.c,v retrieving revision 1.3 diff -p -u -3 -r1.3 unassmbl.c --- src/debug/edebug/unassmbl.c 1997/10/28 19:35:18 1.3 +++ src/debug/edebug/unassmbl.c 2002/01/05 12:28:00 @@ -891,24 +891,45 @@ add_file(char *name) { if(!f) return -1; - if (files == 0) + if (files == 0) { files = (line_info *)malloc(sizeof(line_info)); - else - files = realloc(files, (last_file+1) * sizeof(line_info)); + if (!files) + return -1; + } else { + line_info *temp = realloc(files, (last_file+1) * sizeof(line_info)); + if (!temp) + return -1; + files = temp; + } files[last_file].filename = (char *)malloc(strlen(name)+1); + if (!files[last_file].filename) + return -1; strcpy(files[last_file].filename, name); /* ** build an array of line offsets in real memory. */ lines = malloc(sizeof(long)); + if (!lines) { + free(files[last_file].filename); + files[last_file].filename = NULL; + return -1; + } lines[curline++] = curpos = 0L; while((c = getc(f)) != EOF) { curpos++; if(c == '\n') { - lines = realloc(lines,sizeof(long)*(curline+1)); + long *temp = realloc(lines,sizeof(long)*(curline+1)); + if (!temp) { + free(files[last_file].filename); + files[last_file].filename = NULL; + free(lines); + lines = NULL; + break; + } + lines = temp; lines[curline++] = curpos; } } @@ -917,6 +938,9 @@ add_file(char *name) { */ files[last_file].offsets = lines; fclose(f); + + if (!files[last_file].offsets) + return -1; last_file++; return 0; Index: src/debug/fsdb/unassmbl.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/debug/fsdb/unassmbl.c,v retrieving revision 1.3 diff -p -u -3 -r1.3 unassmbl.c --- src/debug/fsdb/unassmbl.c 1998/09/07 18:12:42 1.3 +++ src/debug/fsdb/unassmbl.c 2002/01/05 12:28:01 @@ -968,23 +968,44 @@ add_file(char *name) { if(!f) return -1; - if (files == 0) + if (files == 0) { files = (line_info *)malloc(sizeof(line_info)); - else - files = realloc(files, (last_file+1) * sizeof(line_info)); + if (!files) + return -1; + } else { + line_info *temp = realloc(files, (last_file+1) * sizeof(line_info)); + if (!temp) + return -1; + files = temp; + } files[last_file].filename = strdup(name); + if (!files[last_file].filename) + return -1; /* ** build an array of line offsets in real memory. */ lines = malloc(sizeof(long)); + if (!lines) { + free(files[last_file].filename); + files[last_file].filename = NULL; + return -1; + } lines[curline++] = curpos = 0L; while((c = getc(f)) != EOF) { curpos++; if(c == '\n') { - lines = realloc(lines,sizeof(long)*(curline+1)); + long *temp = realloc(lines,sizeof(long)*(curline+1)); + if (!temp) { + free(files[last_file].filename); + files[last_file].filename = NULL; + free(lines); + lines = NULL; + break; + } + lines = temp; lines[curline++] = curpos; } } @@ -993,6 +1014,9 @@ add_file(char *name) { */ files[last_file].offsets = lines; files[last_file].line_count = curline; + + if (!files[last_file].offsets) + return -1; last_file++; return 0; Index: src/makemake.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/makemake.c,v retrieving revision 1.1 diff -p -u -3 -r1.1 makemake.c --- src/makemake.c 1998/01/01 18:15:34 1.1 +++ src/makemake.c 2002/01/05 12:28:07 @@ -1,3 +1,4 @@ +/* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include @@ -87,6 +88,12 @@ find(void) } *path_end = '/'; subs = (char **)malloc(msubs*sizeof(char *)); + if (subs == NULL) + { + fprintf(stderr, "Error: Unable to allocate memory at %s:%d\n", + __FILE__, __LINE__); + exit(EXIT_FAILURE); + } while (de = readdir(d)) { /* Skip . and .. */ @@ -107,8 +114,20 @@ find(void) { msubs += 10; subs = (char **)realloc(subs, msubs * sizeof(char *)); + if (subs == NULL) + { + fprintf(stderr, "Error: Unable to reallocate memory at %s:%d\n", + __FILE__, __LINE__); + exit(EXIT_FAILURE); + } } subs[nsubs] = (char *)malloc(strlen(de->d_name)+1); + if (subs[nsubs] == NULL) + { + fprintf(stderr, "Error: Unable to allocate memory at %s:%d\n", + __FILE__, __LINE__); + exit(EXIT_FAILURE); + } strcpy(subs[nsubs], de->d_name); nsubs++; } Index: src/mkdoc/mkdoc.cc =================================================================== RCS file: /cvs/djgpp/djgpp/src/mkdoc/mkdoc.cc,v retrieving revision 1.4 diff -p -u -3 -r1.4 mkdoc.cc --- src/mkdoc/mkdoc.cc 1999/12/14 12:01:35 1.4 +++ src/mkdoc/mkdoc.cc 2002/01/05 12:28:08 @@ -1,3 +1,4 @@ +/* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */ @@ -143,6 +144,11 @@ Node::extend_portability_note(char *str) { int newsize = strlen (last_port_note->note) + strlen (str) + 1; char *newstring = (char *) realloc (last_port_note->note, newsize); + if (!newstring) + { + error("unable to reallocate memory at %s:%d", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } strcat (newstring, str); last_port_note->note = newstring; } @@ -176,6 +182,12 @@ Node::read_portability_note(char *str) p->number = 0; p->target = targ_num; p->note = strdup (""); + + if (!p->note) + { + error("unable to allocate memory at %s:%d", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } if (port_notes) { Index: src/utils/texi2ps/ifset.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/utils/texi2ps/ifset.c,v retrieving revision 1.3 diff -p -u -3 -r1.3 ifset.c --- src/utils/texi2ps/ifset.c 2001/07/02 14:26:25 1.3 +++ src/utils/texi2ps/ifset.c 2002/01/05 12:28:09 @@ -82,6 +82,11 @@ alloc_flag(size_t need_bytes) { /* Initial allocation. */ flag_table = (char *)malloc(INITIAL_SIZE); + if (flag_table == NULL) + { + fprintf(stderr, "\nError: memory exhausted at %s", fileio_where()); + exit (EXIT_FAILURE); + } flag_table_size = INITIAL_SIZE; flag_table[0] = flag_table[1] = '\0'; used_size = 2; @@ -125,8 +130,15 @@ alloc_flag(size_t need_bytes) } if (need_realloc) - /* What? 1KB isn't enough for them?? Oh, well... */ - flag_table = (char *)realloc(flag_table, flag_table_size); + { + /* What? 1KB isn't enough for them?? Oh, well... */ + flag_table = (char *)realloc(flag_table, flag_table_size); + if (flag_table == NULL) + { + fprintf(stderr, "\nError: memory exhausted at %s", fileio_where()); + exit (EXIT_FAILURE); + } + } } if (flag_table == (char *)0) @@ -134,7 +146,7 @@ alloc_flag(size_t need_bytes) fprintf(stderr, "Error: too many flags set: memory exhausted at %s\n", fileio_where()); - exit (1); + exit (EXIT_FAILURE); } return flag_table + used_size - 1; @@ -203,6 +215,11 @@ flag_value(char *name) screenio_print("Warning: flag `%s\' wasn\'t set, but its value used at %s", name, fileio_where()); sprintf(p, no_value_fmt, name); + } + else + { + fprintf(stderr, "\nError: memory exhausted at %s", fileio_where()); + exit (EXIT_FAILURE); } return p; } Index: src/utils/texi2ps/texi2ps.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/utils/texi2ps/texi2ps.c,v retrieving revision 1.3 diff -p -u -3 -r1.3 texi2ps.c --- src/utils/texi2ps/texi2ps.c 1999/02/20 21:56:07 1.3 +++ src/utils/texi2ps/texi2ps.c 2002/01/05 12:28:11 @@ -964,7 +964,7 @@ cm_value(int se, char *flag) else { fprintf(stderr, "\nError: memory exhausted at %s", fileio_where()); - exit(1); + exit(EXIT_FAILURE); } } else @@ -1247,7 +1247,7 @@ skip_until_setfilename() } } fprintf(stderr, "error: no @setfilename\n"); - exit(1); + exit(EXIT_FAILURE); } void @@ -1401,7 +1401,7 @@ usage(void) printf(" -U = clear (unset) flags called `name\'\n"); printf(" -2 = print two columns per page\n"); printf(" -menu = print menus\n"); - exit(0); + exit(EXIT_SUCCESS); } int Index: zoneinfo/src/strftime.c =================================================================== RCS file: /cvs/djgpp/djgpp/zoneinfo/src/strftime.c,v retrieving revision 1.2 diff -p -u -3 -r1.2 strftime.c --- zoneinfo/src/strftime.c 1998/05/28 16:56:10 1.2 +++ zoneinfo/src/strftime.c 2002/01/05 12:28:19 @@ -610,8 +610,15 @@ _loc P((void)) goto bad_locale; bufsize = namesize + st.st_size; locale_buf = NULL; - lbuf = (lbuf == NULL || lbuf == locale_buf_C) ? - malloc(bufsize) : realloc(lbuf, bufsize); + if (lbuf == NULL || lbuf == locale_buf_C) { + lbuf = malloc(bufsize); + } else { + char *temp = realloc(lbuf, bufsize); + /* Don't leak memory if realloc() fails. */ + if (temp == NULL) + free(lbuf); + lbuf = temp; + } if (lbuf == NULL) goto bad_locale; (void) strcpy(lbuf, name); Index: tests/libclink/objs.cc =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libclink/objs.cc,v retrieving revision 1.1 diff -p -u -3 -r1.1 objs.cc --- tests/libclink/objs.cc 1994/11/29 08:24:16 1.1 +++ tests/libclink/objs.cc 2002/01/05 12:28:19 @@ -1,3 +1,4 @@ +#include #include #include @@ -6,6 +7,14 @@ Object *Object::first = 0; +static void +memory_failure (const char *file, const int line) +{ + fprintf(stderr, "Error: Unable to allocate memory at %s:%d\n", + __FILE__, __LINE__); + exit(EXIT_FAILURE); +} + Object::Object(char *Pname) { name = new char[strlen(Pname)+1]; @@ -22,9 +31,11 @@ Object::~Object() ObjList::ObjList() { - objs = (Object **)malloc(10*sizeof(Object *)); - max = 10; count = 0; + max = 10; + objs = (Object **)malloc(max * sizeof(Object *)); + if (!objs) + memory_failure(__FILE__, __LINE__); } ObjList::~ObjList() @@ -42,6 +53,8 @@ void ObjList::add(Object *o) { max += 10; objs = (Object **)realloc(objs, max * sizeof(Object *)); + if (!objs) + memory_failure(__FILE__, __LINE__); } objs[count++] = o; } Index: tests/libclink/slist.cc =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libclink/slist.cc,v retrieving revision 1.2 diff -p -u -3 -r1.2 slist.cc --- tests/libclink/slist.cc 1997/09/07 22:54:34 1.2 +++ tests/libclink/slist.cc 2002/01/05 12:28:19 @@ -4,12 +4,22 @@ #include "slist.h" +static void +memory_failure (const char *file, const int line) +{ + fprintf(stderr, "Error: Unable to allocate memory at %s:%d\n", + __FILE__, __LINE__); + exit(EXIT_FAILURE); +} + StringList::StringList() { count = 0; max = 10; maxc = 0; - data = (char **)malloc(10*sizeof(char *)); + data = (char **)malloc(max * sizeof(char *)); + if (!data) + memory_failure(__FILE__, __LINE__); } StringList::~StringList() @@ -46,8 +56,12 @@ void StringList::add(char *s) { max += 10; data = (char **)realloc(data, max * sizeof(char *)); + if (!data) + memory_failure(__FILE__, __LINE__); } data[maxc] = (char *)malloc(strlen(s)+1); + if (!data[maxc]) + memory_failure(__FILE__, __LINE__); strcpy(data[maxc], s); count++; maxc++; Index: src/docs/kb/wc204.txi =================================================================== RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v retrieving revision 1.103 diff -p -u -3 -r1.103 wc204.txi --- src/docs/kb/wc204.txi 2001/12/09 20:18:07 1.103 +++ src/docs/kb/wc204.txi 2002/01/05 12:28:23 @@ -700,3 +700,25 @@ versions can be built. Profiling option for certain files in the C libraries' sources. The build system for @file{emu387.dxe}, the math co-processor emulation library, was also modified, so that it can be built against a profiled version of libc. + +@cindex FSEXT memory leaks +A memory leak under low-memory conditions was fixed in +the File System Extension code. + +@findex glob AT r{, and memory leaks} +@findex regcomp AT r{, and memory leaks} +Memory leaks under low-memory conditions were fixed in +the functions @code{glob} and @code{regcomp}. + +@pindex fsbd AT r{, and memory leaks} +@pindex edebug32 AT r{, and memory leaks} +@pindex texi2ps AT r{, and memory leaks} +Memory leaks under low-memory conditions were fixed in +the programs @code{fsdb}, @code{edebug32} and @code{texi2ps}. + +@cindex Build system and memory leaks +@cindex Test system and memory leaks +Memory leaks under low-memory conditions were fixed in many of +the programs used to build the DJGPP libraries and documentation +and test the DJGPP libraries: @code{chew}, @code{date}, @code{djasm}, +@code{makemake}, @code{mkdoc} and @code{check}.