diff --git a/gawk-3.1.5-freewstr.patch b/gawk-3.1.5-freewstr.patch index f96dc83..5cac1fd 100644 --- a/gawk-3.1.5-freewstr.patch +++ b/gawk-3.1.5-freewstr.patch @@ -1,17 +1,24 @@ ---- gawk-3.1.5/field.c.freewstr 2007-01-12 12:48:50.000000000 +0100 -+++ gawk-3.1.5/field.c 2007-01-12 12:50:27.000000000 +0100 -@@ -211,6 +211,9 @@ - - n->stptr = cops; - unref(fields_arr[i]); -+ n->wstptr = NULL; -+ n->wstlen = 0; -+ n->flags &= ~WSTRCUR; - fields_arr[i] = n; +--- 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"); } - cops += fields_arr[i]->stlen + ofslen; --- gawk-3.1.5/builtin.c.freewstr 2005-07-26 20:07:43.000000000 +0200 -+++ gawk-3.1.5/builtin.c 2007-01-12 12:48:51.000000000 +0100 ++++ gawk-3.1.5/builtin.c 2007-01-15 11:12:52.000000000 +0100 @@ -2089,9 +2089,9 @@ } @@ -42,7 +49,7 @@ 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-12 12:48:51.000000000 +0100 ++++ 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)); @@ -53,9 +60,17 @@ #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-12 12:48:50.000000000 +0100 -+++ gawk-3.1.5/node.c 2007-01-12 12:48:51.000000000 +0100 -@@ -218,15 +218,7 @@ +--- 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; @@ -72,7 +87,7 @@ return s; } -@@ -289,8 +281,14 @@ +@@ -289,8 +282,14 @@ *r = *n; r->flags &= ~(PERM|TEMP|FIELD); r->flags |= MALLOC; @@ -88,7 +103,7 @@ #endif /* defined MBS_SUPPORT */ if (n->type == Node_val && (n->flags & STRCUR) != 0) { r->stref = 1; -@@ -346,11 +344,7 @@ +@@ -346,11 +345,7 @@ r->stref = 1; r->stptr = NULL; r->stlen = 0; @@ -101,7 +116,7 @@ #endif /* GAWKDEBUG */ return r; } -@@ -365,10 +359,11 @@ +@@ -365,10 +360,11 @@ getnode(r); r->type = Node_val; r->flags = (STRING|STRCUR|MALLOC); @@ -115,7 +130,7 @@ if (flags & ALREADY_MALLOCED) r->stptr = s; else { -@@ -512,20 +507,13 @@ +@@ -512,20 +508,13 @@ return; } free(tmp->stptr); @@ -138,20 +153,32 @@ freenode(tmp); return; } -@@ -708,11 +696,8 @@ +@@ -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); ++ if (n->wstptr != NULL) ++ free_wstr(n); + } /* - * After consideration and consultation, this +@@ -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; } @@ -164,30 +191,53 @@ + if ((n->flags & WSTRCUR) != 0) { + assert(n->wstptr != NULL); + free(n->wstptr); -+ n->wstptr = NULL; -+ n->wstlen = 0; -+ n->flags &= ~WSTRCUR; + } ++ n->wstptr = NULL; ++ n->wstlen = 0; ++ n->flags &= ~WSTRCUR; +} + #if 0 static void dump_wstr(FILE *fp, const wchar_t *str, size_t len) -@@ -839,11 +838,10 @@ - h = towlower(*start); - n = towlower(needle[j]); - if (h != n) -- goto out; -+ continue; - } - return haystack + i; - } --out: ; - } +--- 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 @@ - return NULL; ---- gawk-3.1.5/eval.c.freewstr 2007-01-12 12:48:50.000000000 +0100 -+++ gawk-3.1.5/eval.c 2007-01-12 12:48:51.000000000 +0100 + 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; diff --git a/gawk-3.1.5-mbread.patch b/gawk-3.1.5-mbread.patch new file mode 100644 index 0000000..75ad330 --- /dev/null +++ b/gawk-3.1.5-mbread.patch @@ -0,0 +1,40 @@ + + Date: Mon, 18 Dec 2006 18:38:13 +0300 + From: "Dmitry V. Levin" + Subject: gawk: do_match() invalid read + To: bug-gawk@gnu.org + + Due to missing mounds check, do_match() may do invalid read in multibyte + locales: + + $ printf '\n\n' |env -i gawk '{print match(""," *")}' + 1 + 1 + $ printf '\n\n' |env -i LC_ALL=3Dru_RU.UTF-8 gawk '{print match(""," *")}' + -1208299079 + 134843273 + + As you see, match() output in multibyte locale is wrong; valgrind reports + about "Invalid read of size 4". + + +--- gawk-3.1.5/builtin.c.mbread 2007-01-12 13:23:55.000000000 +0100 ++++ gawk-3.1.5/builtin.c 2007-01-12 13:24:41.000000000 +0100 +@@ -2020,7 +2020,7 @@ + + rlength = REEND(rp, t1->stptr) - RESTART(rp, t1->stptr); /* byte length */ + #ifdef MBS_SUPPORT +- if (gawk_mb_cur_max > 1) { ++ if (rlength > 0 && gawk_mb_cur_max > 1) { + t1 = str2wstr(t1, & wc_indices); + rlength = wc_indices[rstart + rlength - 1] - wc_indices[rstart] + 1; + rstart = wc_indices[rstart]; +@@ -2046,7 +2046,7 @@ + subpat_start = s; + subpat_len = len = SUBPATEND(rp, t1->stptr, ii) - s; + #ifdef MBS_SUPPORT +- if (gawk_mb_cur_max > 1) { ++ if (len > 0 && gawk_mb_cur_max > 1) { + subpat_start = wc_indices[s]; + subpat_len = wc_indices[s + len - 1] - subpat_start + 1; + } diff --git a/gawk.spec b/gawk.spec index 9c5428d..a029d9b 100644 --- a/gawk.spec +++ b/gawk.spec @@ -1,7 +1,7 @@ Summary: The GNU version of the awk text processing utility. Name: gawk Version: 3.1.5 -Release: 13%{dist} +Release: 14%{?dist} License: GPL Group: Applications/Text Source0: ftp://ftp.gnu.org/gnu/gawk/gawk-%{version}.tar.bz2 @@ -31,6 +31,8 @@ Patch9: gawk-3.1.5-numflags.patch Patch10: gawk-3.1.5-ipv6.patch # 222080 - double free or corruption Patch11: gawk-3.1.5-freewstr.patch +# upstream patch - Invalid read of size 4 +Patch12: gawk-3.1.5-mbread.patch %description The gawk packages contains the GNU version of awk, a text processing @@ -53,6 +55,7 @@ considered to be a standard Linux tool for processing text. %patch9 -p1 -b .numflag %patch10 -p1 -b .ipv6 %patch11 -p1 -b .freewstr +%patch12 -p1 -b .mbread %build %configure @@ -101,6 +104,13 @@ fi %{_datadir}/awk %changelog +* Mon Jan 15 2007 Karel Zak 3.1.5-14 +- sync with double-free upstream fixes +- fix #222531: Replace dist by ?dist + +* Fri Jan 12 2007 Karel Zak 3.1.5-13 +- fix MB read + * Fri Jan 12 2007 Karel Zak 3.1.5-13 - improve freewstr patch