--- gawk-3.1.5/field.c.freewstr 2007-01-15 11:02:51.000000000 +0100 +++ gawk-3.1.5/field.c 2007-01-15 11:21:56.000000000 +0100 @@ -155,6 +155,7 @@ ofs = force_string(OFS_node->var_value); ofslen = ofs->stlen; for (i = NF; i > 0; i--) { + free_wstr(fields_arr[i]); tmp = fields_arr[i]; tmp = force_string(tmp); tlen += tmp->stlen; @@ -922,7 +923,7 @@ FIELDWIDTHS[0] = 0; for (i = 1; ; i++) { unsigned long int tmp; - if (i >= fw_alloc) { + if (i + 1 >= fw_alloc) { fw_alloc *= 2; erealloc(FIELDWIDTHS, int *, fw_alloc * sizeof(int), "set_FIELDWIDTHS"); } --- gawk-3.1.5/builtin.c.freewstr 2005-07-26 20:07:43.000000000 +0200 +++ gawk-3.1.5/builtin.c 2007-01-15 11:12:52.000000000 +0100 @@ -2089,9 +2089,9 @@ } free(buf); - if (wc_indices != NULL) - free(wc_indices); } + if (wc_indices != NULL) + free(wc_indices); } else { /* match failed */ rstart = 0; rlength = -1; @@ -2462,6 +2462,8 @@ free(t->stptr); t->stptr = buf; t->stlen = textlen; + free_wstr(t); + t->flags &= ~(NUMCUR|NUMBER); free_temp(s); if (matches > 0 && lhs) { @@ -2471,7 +2473,6 @@ } if (after_assign != NULL) (*after_assign)(); - t->flags &= ~(NUMCUR|NUMBER); } if (mb_indices != NULL) free(mb_indices); --- gawk-3.1.5/awk.h.freewstr 2005-07-26 20:07:43.000000000 +0200 +++ gawk-3.1.5/awk.h 2007-01-15 11:02:51.000000000 +0100 @@ -1166,6 +1166,9 @@ #define force_wstring(n) str2wstr(n, NULL) extern const wchar_t *wstrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len)); extern const wchar_t *wcasestrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len)); +extern void free_wstr P((NODE *n)); +#else +#define free_wstr(NODE) /* empty */ #endif /* re.c */ extern Regexp *make_regexp P((const char *s, size_t len, int ignorecase, int dfa)); --- gawk-3.1.5/node.c.freewstr 2007-01-15 11:02:51.000000000 +0100 +++ gawk-3.1.5/node.c 2007-01-15 11:33:44.000000000 +0100 @@ -96,6 +96,7 @@ if (! do_traditional && isnondecimal(cp, TRUE)) { n->numbr = nondec2awknum(cp, cpend - cp); n->flags |= NUMCUR; + ptr = cpend; goto finish; } } @@ -218,15 +219,7 @@ no_malloc: s->stref = 1; s->flags |= STRCUR; -#if defined MBS_SUPPORT - if ((s->flags & WSTRCUR) != 0) { - assert(s->wstptr != NULL); - free(s->wstptr); - s->wstptr = NULL; - s->wstlen = 0; - s->flags &= ~WSTRCUR; - } -#endif + free_wstr(s); return s; } @@ -289,8 +282,14 @@ *r = *n; r->flags &= ~(PERM|TEMP|FIELD); r->flags |= MALLOC; -#if defined MBS_SUPPORT +#ifdef MBS_SUPPORT + /* + * DON'T call free_wstr(r) here! + * r->wstptr still points at n->wstptr's value, and we + * don't want to free it! + */ r->wstptr = NULL; + r->wstlen = 0; #endif /* defined MBS_SUPPORT */ if (n->type == Node_val && (n->flags & STRCUR) != 0) { r->stref = 1; @@ -346,11 +345,7 @@ r->stref = 1; r->stptr = NULL; r->stlen = 0; -#if defined MBS_SUPPORT - r->wstptr = NULL; - r->wstlen = 0; - r->flags &= ~WSTRCUR; -#endif /* MBS_SUPPORT */ + free_wstr(r); #endif /* GAWKDEBUG */ return r; } @@ -365,10 +360,11 @@ getnode(r); r->type = Node_val; r->flags = (STRING|STRCUR|MALLOC); -#if defined MBS_SUPPORT +#ifdef MBS_SUPPORT r->wstptr = NULL; r->wstlen = 0; -#endif +#endif /* defined MBS_SUPPORT */ + if (flags & ALREADY_MALLOCED) r->stptr = s; else { @@ -512,20 +508,13 @@ return; } free(tmp->stptr); -#if defined MBS_SUPPORT - if (tmp->wstptr != NULL) { - assert((tmp->flags & WSTRCUR) != 0); - free(tmp->wstptr); - } - tmp->flags &= ~WSTRCUR; - tmp->wstptr = NULL; - tmp->wstlen = 0; -#endif + free_wstr(tmp); } freenode(tmp); return; } if ((tmp->flags & FIELD) != 0) { + free_wstr(tmp); freenode(tmp); return; } @@ -706,12 +695,8 @@ return n; /* otherwise fall through and recompute to fill in the array */ - } - - if (n->wstptr != NULL) { - free(n->wstptr); - n->wstptr = NULL; - n->wstlen = 0; + if (n->wstptr != NULL) + free_wstr(n); } /* @@ -752,8 +737,8 @@ case (size_t) -2: case (size_t) -1: case 0: - goto done; - + count = 1; + /* fall through */ default: *wsp++ = wc; src_count -= count; @@ -777,6 +762,20 @@ return n; } +/* free_wstr --- release the wide string part of a node */ + +void +free_wstr(NODE *n) +{ + if ((n->flags & WSTRCUR) != 0) { + assert(n->wstptr != NULL); + free(n->wstptr); + } + n->wstptr = NULL; + n->wstlen = 0; + n->flags &= ~WSTRCUR; +} + #if 0 static void dump_wstr(FILE *fp, const wchar_t *str, size_t len) --- gawk-3.1.5/dfa.c.freewstr 2007-01-15 11:13:19.000000000 +0100 +++ gawk-3.1.5/dfa.c 2007-01-15 11:17:44.000000000 +0100 @@ -516,7 +516,6 @@ work_mbc->nchars = work_mbc->nranges = work_mbc->nch_classes = 0; work_mbc->nequivs = work_mbc->ncoll_elems = 0; - work_mbc->chars = NULL; work_mbc->ch_classes = NULL; work_mbc->range_sts = work_mbc->range_ends = NULL; work_mbc->equivs = work_mbc->coll_elems = NULL; @@ -1602,8 +1601,8 @@ d->states[i].constraint = 0; d->states[i].first_end = 0; #ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - d->states[i].mbps.nelem = 0; + d->states[i].mbps.nelem = 0; + d->states[i].mbps.elems = NULL; #endif for (j = 0; j < s->nelem; ++j) if (d->tokens[s->elems[j].index] < 0) @@ -3136,8 +3135,13 @@ } #endif /* MBS_SUPPORT */ - for (i = 0; i < d->sindex; ++i) + for (i = 0; i < d->sindex; ++i) { free((ptr_t) d->states[i].elems.elems); +#ifdef MBS_SUPPORT + if (d->states[i].mbps.nelem > 0) + free((ptr_t) d->states[i].mbps.elems); +#endif /* MBS_SUPPORT */ + } free((ptr_t) d->states); for (i = 0; i < d->tindex; ++i) if (d->follows[i].elems) --- gawk-3.1.5/eval.c.freewstr 2007-01-15 11:02:51.000000000 +0100 +++ gawk-3.1.5/eval.c 2007-01-15 11:02:51.000000000 +0100 @@ -1176,13 +1176,7 @@ memcpy(l->stptr + l->stlen, r->stptr, r->stlen); l->stlen += r->stlen; l->stptr[l->stlen] = '\0'; -#if defined MBS_SUPPORT - if (r->wstptr != NULL) - free(r->wstptr); - r->wstptr = NULL; - r->wstlen = 0; - r->flags &= ~WSTRCUR; -#endif /* MBS_SUPPORT */ + free_wstr(l); } else { char *nval; size_t nlen = l->stlen + r->stlen + 2;