Package: gawk
Version: 3.1.5.dfsg-4
Tags: patch

First reported to Ubuntu at https://bugs.launchpad.net/ubuntu/+source/gawk/+bug/58256
Details may be seen there.

Problem has been fixed upstream in CVS; I've attached a debdiff against which backports the relevant source changes.

With the text file below (rc_cmp.txt) in the working directory, the following command produces an error

$ cat rc_cmp.txt | gawk '{length($1)}'
*** glibc detected *** double free or corruption (fasttop): 0x080ae700 ***
Aborted

rc_cmp.txt:
## List of components contained in system rc
## File rc_cmp.txt
## Created by mtt on Wed Aug 30 21:09:19 BST 2006

0
1
C:c
R:r
SS:e1
SS:e2



diff -u gawk-3.1.5.dfsg/debian/patches/00list 
gawk-3.1.5.dfsg/debian/patches/00list
--- gawk-3.1.5.dfsg/debian/patches/00list
+++ gawk-3.1.5.dfsg/debian/patches/00list
@@ -4,0 +5 @@
+25_free_wstr-and-multiple-frees
diff -u gawk-3.1.5.dfsg/debian/changelog gawk-3.1.5.dfsg/debian/changelog
--- gawk-3.1.5.dfsg/debian/changelog
+++ gawk-3.1.5.dfsg/debian/changelog
@@ -1,3 +1,11 @@
+gawk (1:3.1.5.dfsg-5) unstable; urgency=low
+
+  * 25_free_wstr-and-multiple-frees.dpatch: brought in some changes from
+    current CVS, to resolve an issue with multiple frees (closes Malone
+    bug #58256).
+
+ -- Micah Cowan <[EMAIL PROTECTED]>  Fri,  6 Apr 2007 11:33:50 -0700
+
 gawk (1:3.1.5.dfsg-4) unstable; urgency=low
 
   * doc/gawk.info, doc/gawk.texi, doc/gawkinet.info, doc/gawkinet.texi:
only in patch2:
unchanged:
--- gawk-3.1.5.dfsg.orig/debian/patches/25_free_wstr-and-multiple-frees.dpatch
+++ gawk-3.1.5.dfsg/debian/patches/25_free_wstr-and-multiple-frees.dpatch
@@ -0,0 +1,182 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 25_free_wstr-and-multiple-frees.dpatch by  <[EMAIL PROTECTED]>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Brought in from CVS, 6 Apr 2007. This patch was brought in
+## DP: specifically to address an issue with multiple free()s in
+## DP: str2wstr().
+
[EMAIL PROTECTED]@
+diff -urNad gawk-3.1.5.dfsg~/awk.h gawk-3.1.5.dfsg/awk.h
+--- gawk-3.1.5.dfsg~/awk.h     2005-07-26 11:07:43.000000000 -0700
++++ gawk-3.1.5.dfsg/awk.h      2007-04-06 12:17:09.000000000 -0700
+@@ -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));
+diff -urNad gawk-3.1.5.dfsg~/builtin.c gawk-3.1.5.dfsg/builtin.c
+--- gawk-3.1.5.dfsg~/builtin.c 2005-07-26 11:07:43.000000000 -0700
++++ gawk-3.1.5.dfsg/builtin.c  2007-04-06 12:17:09.000000000 -0700
+@@ -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);
+diff -urNad gawk-3.1.5.dfsg~/eval.c gawk-3.1.5.dfsg/eval.c
+--- gawk-3.1.5.dfsg~/eval.c    2007-04-06 12:17:09.000000000 -0700
++++ gawk-3.1.5.dfsg/eval.c     2007-04-06 12:19:52.000000000 -0700
+@@ -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 (l->wstptr != NULL)
+-                               free(l->wstptr);
+-                       l->wstptr = NULL;
+-                       l->wstlen = 0;
+-                       l->flags &= ~WSTRCUR;
+-#endif /* MBS_SUPPORT */
++                      free_wstr(l);
+               } else {
+                       char *nval;
+                       size_t nlen = l->stlen + r->stlen + 2;
+diff -urNad gawk-3.1.5.dfsg~/field.c gawk-3.1.5.dfsg/field.c
+--- gawk-3.1.5.dfsg~/field.c   2005-05-11 08:28:15.000000000 -0700
++++ gawk-3.1.5.dfsg/field.c    2007-04-06 12:17:09.000000000 -0700
+@@ -166,6 +166,7 @@
+       cops = ops;
+       ops[0] = '\0';
+       for (i = 1;  i <= NF; i++) {
++              free_wstr(fields_arr[i]);
+               tmp = fields_arr[i];
+               /* copy field */
+               if (tmp->stlen == 1)
+diff -urNad gawk-3.1.5.dfsg~/node.c gawk-3.1.5.dfsg/node.c
+--- gawk-3.1.5.dfsg~/node.c    2005-07-26 11:07:43.000000000 -0700
++++ gawk-3.1.5.dfsg/node.c     2007-04-06 12:17:09.000000000 -0700
+@@ -216,15 +216,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;
+ }
+ 
+@@ -288,7 +280,13 @@
+       r->flags &= ~(PERM|TEMP|FIELD);
+       r->flags |= MALLOC;
+ #if defined 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;
+@@ -344,11 +342,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;
+ }
+@@ -510,20 +504,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;
+       }
+@@ -702,16 +689,11 @@
+       if ((n->flags & WSTRCUR) != 0) {
+               if (ptr == NULL)
+                       return n;
++              free_wstr(n);
+               /* otherwise
+                       fall through and recompute to fill in the array */
+       }
+ 
+-      if (n->wstptr != NULL) {
+-              free(n->wstptr);
+-              n->wstptr = NULL;
+-              n->wstlen = 0;
+-      }
+-
+       /*
+        * After consideration and consultation, this
+        * code trades space for time. We allocate
+@@ -775,6 +757,22 @@
+       return n;
+ }
+ 
++/* free_wstr --- release the wide string part of a node */
++
++void
++free_wstr(NODE *n)
++{
++      assert(n->type == Node_val);
++
++      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)

Reply via email to