commit:     73c81e707231bcd1a849040ca837e2a21a451d04
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Wed Jan 18 09:43:12 2017 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Wed Jan 18 09:56:42 2017 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=73c81e70

sys-apps/sed: add upstream fixes for some newline handling which causes 
segfaults

 sys-apps/sed/files/sed-4.3-dfa-segv-1.patch        | 175 +++++++++++++++++++++
 sys-apps/sed/files/sed-4.3-dfa-segv-2.patch        | 112 +++++++++++++
 sys-apps/sed/files/sed-4.3-dfa-segv-3.patch        | 146 +++++++++++++++++
 sys-apps/sed/{sed-4.3.ebuild => sed-4.3-r1.ebuild} |   9 +-
 4 files changed, 440 insertions(+), 2 deletions(-)

diff --git a/sys-apps/sed/files/sed-4.3-dfa-segv-1.patch 
b/sys-apps/sed/files/sed-4.3-dfa-segv-1.patch
new file mode 100644
index 00000000..f82adc7
--- /dev/null
+++ b/sys-apps/sed/files/sed-4.3-dfa-segv-1.patch
@@ -0,0 +1,175 @@
+fix from upstream gnulib (fudged to apply to sed-4.3)
+
+From 823b5cb589366f7c8742503af980803afad0978f Mon Sep 17 00:00:00 2001
+From: Paul Eggert <[email protected]>
+Date: Sun, 8 Jan 2017 12:44:29 -0800
+Subject: [PATCH] dfa: fix reallocation bug when matching newlines
+
+Problem reported for sed by S. Gilles (Bug#25390).
+* lib/dfa.c (realloc_trans_if_necessary): Move earlier.
+(dfastate): Reallocate before moving any newline transition ...
+(build_state): ... instead of reallocating here, where it is too late.
+---
+ ChangeLog |   8 +++++
+ lib/dfa.c | 114 ++++++++++++++++++++++++++++++--------------------------------
+ 2 files changed, 63 insertions(+), 59 deletions(-)
+
+diff --git a/lib/dfa.c b/lib/dfa.c
+index 8276db160a4b..141888a978fa 100644
+--- a/lib/dfa.c
++++ b/lib/dfa.c
+@@ -2574,6 +2574,40 @@ dfaanalyze (struct dfa *d, bool searchflag)
+   free (merged.elems);
+ }
+ 
++/* Make sure D's state arrays are large enough to hold NEW_STATE.  */
++static void
++realloc_trans_if_necessary (struct dfa *d, state_num new_state)
++{
++  state_num oldalloc = d->tralloc;
++  if (oldalloc <= new_state)
++    {
++      state_num **realtrans = d->trans ? d->trans - 2 : NULL;
++      ptrdiff_t newalloc1 = realtrans ? d->tralloc + 2 : 0;
++      realtrans = xpalloc (realtrans, &newalloc1, new_state - oldalloc + 1,
++                           -1, sizeof *realtrans);
++      realtrans[0] = realtrans[1] = NULL;
++      d->trans = realtrans + 2;
++      ptrdiff_t newalloc = d->tralloc = newalloc1 - 2;
++      d->fails = xnrealloc (d->fails, newalloc, sizeof *d->fails);
++      d->success = xnrealloc (d->success, newalloc, sizeof *d->success);
++      d->newlines = xnrealloc (d->newlines, newalloc, sizeof *d->newlines);
++      if (d->localeinfo.multibyte)
++        {
++          realtrans = d->mb_trans ? d->mb_trans - 2 : NULL;
++          realtrans = xnrealloc (realtrans, newalloc1, sizeof *realtrans);
++          if (oldalloc == 0)
++            realtrans[0] = realtrans[1] = NULL;
++          d->mb_trans = realtrans + 2;
++        }
++      for (; oldalloc < newalloc; oldalloc++)
++        {
++          d->trans[oldalloc] = NULL;
++          d->fails[oldalloc] = NULL;
++          if (d->localeinfo.multibyte)
++            d->mb_trans[oldalloc] = NULL;
++        }
++    }
++}
+ 
+ /* Return the transition out of state s of d for the input character uc,
+    updating the slots in trans accordingly.
+@@ -2810,20 +2844,25 @@ dfastate (state_num s, struct dfa *d, unsigned char 
uc, state_num trans[])
+     }
+ 
+   /* Set the transitions for each character in the label.  */
++  state_num maxstate = -1;
+   for (i = 0; i < NOTCHAR; i++)
+     if (tstbit (i, label))
+-      switch (d->syntax.sbit[i])
+-        {
+-        case CTX_NEWLINE:
+-          trans[i] = state_newline;
+-          break;
+-        case CTX_LETTER:
+-          trans[i] = state_letter;
+-          break;
+-        default:
+-          trans[i] = state;
+-          break;
+-        }
++      {
++        switch (d->syntax.sbit[i])
++          {
++          case CTX_NEWLINE:
++            trans[i] = state_newline;
++            break;
++          case CTX_LETTER:
++            trans[i] = state_letter;
++            break;
++          default:
++            trans[i] = state;
++            break;
++          }
++        if (maxstate < trans[i])
++          maxstate = trans[i];
++      }
+ 
+ #ifdef DEBUG
+   fprintf (stderr, "trans table %td", s);
+@@ -2840,6 +2879,9 @@ dfastate (state_num s, struct dfa *d, unsigned char uc, 
state_num trans[])
+   free (follows.elems);
+   free (tmp.elems);
+ 
++  /* Reallocate now, to reallocate any newline transition properly.  */
++  realloc_trans_if_necessary (d, maxstate);
++
+   /* Keep the newline transition in a special place so we can use it as
+      a sentinel.  */
+   if (tstbit (d->syntax.eolbyte, label))
+@@ -2851,42 +2893,6 @@ dfastate (state_num s, struct dfa *d, unsigned char uc, 
state_num trans[])
+   return trans[uc];
+ }
+ 
+-/* Make sure D's state arrays are large enough to hold NEW_STATE.  */
+-static void
+-realloc_trans_if_necessary (struct dfa *d, state_num new_state)
+-{
+-  state_num oldalloc = d->tralloc;
+-  if (oldalloc <= new_state)
+-    {
+-      state_num **realtrans = d->trans ? d->trans - 2 : NULL;
+-      ptrdiff_t newalloc, newalloc1;
+-      newalloc1 = realtrans ? d->tralloc + 2 : 0;
+-      realtrans = xpalloc (realtrans, &newalloc1, new_state - oldalloc + 1,
+-                           -1, sizeof *realtrans);
+-      realtrans[0] = realtrans[1] = NULL;
+-      d->trans = realtrans + 2;
+-      d->tralloc = newalloc = newalloc1 - 2;
+-      d->fails = xnrealloc (d->fails, newalloc, sizeof *d->fails);
+-      d->success = xnrealloc (d->success, newalloc, sizeof *d->success);
+-      d->newlines = xnrealloc (d->newlines, newalloc, sizeof *d->newlines);
+-      if (d->localeinfo.multibyte)
+-        {
+-          realtrans = d->mb_trans ? d->mb_trans - 2 : NULL;
+-          realtrans = xnrealloc (realtrans, newalloc1, sizeof *realtrans);
+-          if (oldalloc == 0)
+-            realtrans[0] = realtrans[1] = NULL;
+-          d->mb_trans = realtrans + 2;
+-        }
+-      for (; oldalloc < newalloc; oldalloc++)
+-        {
+-          d->trans[oldalloc] = NULL;
+-          d->fails[oldalloc] = NULL;
+-          if (d->localeinfo.multibyte)
+-            d->mb_trans[oldalloc] = NULL;
+-        }
+-    }
+-}
+-
+ /* Calculate the transition table for a new state derived from state s
+    for a compiled dfa d after input character uc, and return the new
+    state number.  */
+@@ -2932,18 +2939,7 @@ build_state (state_num s, struct dfa *d, unsigned char 
uc)
+   if (ACCEPTS_IN_CONTEXT (d->states[s].context, CTX_NONE, s, *d))
+     d->success[s] |= CTX_NONE;
+ 
+-  s = dfastate (s, d, uc, trans);
+-
+-  /* Now go through the new transition table, and make sure that the trans
+-     and fail arrays are allocated large enough to hold a pointer for the
+-     largest state mentioned in the table.  */
+-  state_num maxstate = -1;
+-  for (int i = 0; i < NOTCHAR; i++)
+-    if (maxstate < trans[i])
+-      maxstate = trans[i];
+-  realloc_trans_if_necessary (d, maxstate);
+-
+-  return s;
++  return dfastate (s, d, uc, trans);
+ }
+ 
+ /* Multibyte character handling sub-routines for dfaexec.  */
+-- 
+2.11.0
+

diff --git a/sys-apps/sed/files/sed-4.3-dfa-segv-2.patch 
b/sys-apps/sed/files/sed-4.3-dfa-segv-2.patch
new file mode 100644
index 00000000..4e4fb2c
--- /dev/null
+++ b/sys-apps/sed/files/sed-4.3-dfa-segv-2.patch
@@ -0,0 +1,112 @@
+fix from upstream gnulib (fudged to apply to sed-4.3)
+
+From aff55692da81f702ccbc461ad4f896b23c398638 Mon Sep 17 00:00:00 2001
+From: Norihiro Tanaka <[email protected]>
+Date: Mon, 9 Jan 2017 07:46:13 +0900
+Subject: [PATCH] dfa: simplify transition table allocation
+
+* src/dfa.c (realloc_trans_if_necessary): Remove second argument.
+Its value is derived from other variable.  Update callers.
+(dfastate): Remove calculation of max number of state.
+---
+ lib/dfa.c | 44 ++++++++++++++++++++------------------------
+ 1 file changed, 20 insertions(+), 24 deletions(-)
+
+diff --git a/lib/dfa.c b/lib/dfa.c
+index 141888a978fa..bda4602b1094 100644
+--- a/lib/dfa.c
++++ b/lib/dfa.c
+@@ -2576,14 +2576,14 @@ dfaanalyze (struct dfa *d, bool searchflag)
+ 
+ /* Make sure D's state arrays are large enough to hold NEW_STATE.  */
+ static void
+-realloc_trans_if_necessary (struct dfa *d, state_num new_state)
++realloc_trans_if_necessary (struct dfa *d)
+ {
+   state_num oldalloc = d->tralloc;
+-  if (oldalloc <= new_state)
++  if (oldalloc < d->sindex)
+     {
+       state_num **realtrans = d->trans ? d->trans - 2 : NULL;
+       ptrdiff_t newalloc1 = realtrans ? d->tralloc + 2 : 0;
+-      realtrans = xpalloc (realtrans, &newalloc1, new_state - oldalloc + 1,
++      realtrans = xpalloc (realtrans, &newalloc1, d->sindex - oldalloc,
+                            -1, sizeof *realtrans);
+       realtrans[0] = realtrans[1] = NULL;
+       d->trans = realtrans + 2;
+@@ -2825,6 +2825,9 @@ dfastate (state_num s, struct dfa *d, unsigned char uc, 
state_num trans[])
+         state_letter = state_index (d, &follows, CTX_LETTER);
+       else
+         state_letter = state;
++
++      /* Reallocate now, to reallocate any newline transition properly.  */
++      realloc_trans_if_necessary (d);
+     }
+ 
+   /* If we are a searching matcher, the default transition is to a state
+@@ -2847,22 +2850,18 @@ dfastate (state_num s, struct dfa *d, unsigned char 
uc, state_num trans[])
+   state_num maxstate = -1;
+   for (i = 0; i < NOTCHAR; i++)
+     if (tstbit (i, label))
+-      {
+-        switch (d->syntax.sbit[i])
+-          {
+-          case CTX_NEWLINE:
+-            trans[i] = state_newline;
+-            break;
+-          case CTX_LETTER:
+-            trans[i] = state_letter;
+-            break;
+-          default:
+-            trans[i] = state;
+-            break;
+-          }
+-        if (maxstate < trans[i])
+-          maxstate = trans[i];
+-      }
++      switch (d->syntax.sbit[i])
++        {
++        case CTX_NEWLINE:
++          trans[i] = state_newline;
++          break;
++        case CTX_LETTER:
++          trans[i] = state_letter;
++          break;
++        default:
++          trans[i] = state;
++          break;
++        }
+ 
+ #ifdef DEBUG
+   fprintf (stderr, "trans table %td", s);
+@@ -2879,9 +2878,6 @@ dfastate (state_num s, struct dfa *d, unsigned char uc, 
state_num trans[])
+   free (follows.elems);
+   free (tmp.elems);
+ 
+-  /* Reallocate now, to reallocate any newline transition properly.  */
+-  realloc_trans_if_necessary (d, maxstate);
+-
+   /* Keep the newline transition in a special place so we can use it as
+      a sentinel.  */
+   if (tstbit (d->syntax.eolbyte, label))
+@@ -3042,7 +3038,7 @@ transit_state (struct dfa *d, state_num s, unsigned char 
const **pp,
+ 
+   separate_contexts = state_separate_contexts (&d->mb_follows);
+   s2 = state_index (d, &d->mb_follows, separate_contexts ^ CTX_ANY);
+-  realloc_trans_if_necessary (d, s2);
++  realloc_trans_if_necessary (d);
+ 
+   d->mb_trans[s][d->states[s1].mb_trindex] = s2;
+ 
+@@ -3137,7 +3133,7 @@ dfaexec_main (struct dfa *d, char const *begin, char 
*end, bool allow_nl,
+     }
+ 
+   if (!d->tralloc)
+-    realloc_trans_if_necessary (d, 0);
++    realloc_trans_if_necessary (d);
+ 
+   s = s1 = 0;
+   p = mbp = (unsigned char const *) begin;
+-- 
+2.11.0
+

diff --git a/sys-apps/sed/files/sed-4.3-dfa-segv-3.patch 
b/sys-apps/sed/files/sed-4.3-dfa-segv-3.patch
new file mode 100644
index 00000000..d85022f
--- /dev/null
+++ b/sys-apps/sed/files/sed-4.3-dfa-segv-3.patch
@@ -0,0 +1,146 @@
+fix from upstream gnulib (fudged to apply to sed-4.3)
+
+From 7c345c68cdf62737ccc4a9d0ba2cd921fae850fa Mon Sep 17 00:00:00 2001
+From: Norihiro Tanaka <[email protected]>
+Date: Mon, 9 Jan 2017 08:21:21 +0900
+Subject: [PATCH] dfa: melt down dfastate into build_state
+
+* src/dfa.c (dfastate): Remove it.
+(build_state): Insert content of dfastate() to bottom.
+---
+ lib/dfa.c | 97 +++++++++++++++++++++++++++++----------------------------------
+ 1 file changed, 45 insertions(+), 52 deletions(-)
+
+diff --git a/lib/dfa.c b/lib/dfa.c
+index bda4602b1094..6896ed320a7b 100644
+--- a/lib/dfa.c
++++ b/lib/dfa.c
+@@ -2609,8 +2609,10 @@ realloc_trans_if_necessary (struct dfa *d)
+     }
+ }
+ 
+-/* Return the transition out of state s of d for the input character uc,
+-   updating the slots in trans accordingly.
++/*
++   Calculate the transition table for a new state derived from state s
++   for a compiled dfa d after input character uc, and return the new
++   state number.
+ 
+    Do not worry about all possible input characters; calculate just the group
+    of positions that match uc.  Label it with the set of characters that
+@@ -2639,8 +2641,9 @@ realloc_trans_if_necessary (struct dfa *d)
+    If after comparing with every group there are characters remaining in C,
+    create a new group labeled with the characters of C and insert this
+    position in that group.  */
++
+ static state_num
+-dfastate (state_num s, struct dfa *d, unsigned char uc, state_num trans[])
++build_state (state_num s, struct dfa *d, unsigned char uc)
+ {
+   leaf_set group;               /* Positions that match the input char.  */
+   charclass label;              /* The group's label.  */
+@@ -2652,6 +2655,45 @@ dfastate (state_num s, struct dfa *d, unsigned char uc, 
state_num trans[])
+   fprintf (stderr, "build state %td\n", s);
+ #endif
+ 
++  /* A pointer to the new transition table, and the table itself.  */
++  state_num **ptrans = (ACCEPTING (s, *d) ? d->fails : d->trans) + s;
++  state_num *trans = *ptrans;
++
++  if (!trans)
++    {
++      /* MAX_TRCOUNT is an arbitrary upper limit on the number of
++         transition tables that can exist at once, other than for
++         initial states.  Often-used transition tables are quickly
++         rebuilt, whereas rarely-used ones are cleared away.  */
++      if (MAX_TRCOUNT <= d->trcount)
++        {
++          for (state_num i = d->min_trcount; i < d->tralloc; i++)
++            {
++              free (d->trans[i]);
++              free (d->fails[i]);
++              d->trans[i] = d->fails[i] = NULL;
++            }
++          d->trcount = 0;
++        }
++
++      d->trcount++;
++      *ptrans = trans = xmalloc (NOTCHAR * sizeof *trans);
++
++      /* Fill transition table with a default value which means that the
++         transited state has not been calculated yet.  */
++      for (int i = 0; i < NOTCHAR; i++)
++        trans[i] = -2;
++    }
++
++  /* Set up the success bits for this state.  */
++  d->success[s] = 0;
++  if (ACCEPTS_IN_CONTEXT (d->states[s].context, CTX_NEWLINE, s, *d))
++    d->success[s] |= CTX_NEWLINE;
++  if (ACCEPTS_IN_CONTEXT (d->states[s].context, CTX_LETTER, s, *d))
++    d->success[s] |= CTX_LETTER;
++  if (ACCEPTS_IN_CONTEXT (d->states[s].context, CTX_NONE, s, *d))
++    d->success[s] |= CTX_NONE;
++
+   group.elems = xnmalloc (d->nleaves, sizeof *group.elems);
+   group.nelem = 0;
+ 
+@@ -2889,55 +2931,6 @@ dfastate (state_num s, struct dfa *d, unsigned char uc, 
state_num trans[])
+   return trans[uc];
+ }
+ 
+-/* Calculate the transition table for a new state derived from state s
+-   for a compiled dfa d after input character uc, and return the new
+-   state number.  */
+-
+-static state_num
+-build_state (state_num s, struct dfa *d, unsigned char uc)
+-{
+-  /* A pointer to the new transition table, and the table itself.  */
+-  state_num **ptrans = (ACCEPTING (s, *d) ? d->fails : d->trans) + s;
+-  state_num *trans = *ptrans;
+-
+-  if (!trans)
+-    {
+-      /* MAX_TRCOUNT is an arbitrary upper limit on the number of
+-         transition tables that can exist at once, other than for
+-         initial states.  Often-used transition tables are quickly
+-         rebuilt, whereas rarely-used ones are cleared away.  */
+-      if (MAX_TRCOUNT <= d->trcount)
+-        {
+-          for (state_num i = d->min_trcount; i < d->tralloc; i++)
+-            {
+-              free (d->trans[i]);
+-              free (d->fails[i]);
+-              d->trans[i] = d->fails[i] = NULL;
+-            }
+-          d->trcount = 0;
+-        }
+-
+-      d->trcount++;
+-      *ptrans = trans = xmalloc (NOTCHAR * sizeof *trans);
+-
+-      /* Fill transition table with a default value which means that the
+-         transited state has not been calculated yet.  */
+-      for (int i = 0; i < NOTCHAR; i++)
+-        trans[i] = -2;
+-    }
+-
+-  /* Set up the success bits for this state.  */
+-  d->success[s] = 0;
+-  if (ACCEPTS_IN_CONTEXT (d->states[s].context, CTX_NEWLINE, s, *d))
+-    d->success[s] |= CTX_NEWLINE;
+-  if (ACCEPTS_IN_CONTEXT (d->states[s].context, CTX_LETTER, s, *d))
+-    d->success[s] |= CTX_LETTER;
+-  if (ACCEPTS_IN_CONTEXT (d->states[s].context, CTX_NONE, s, *d))
+-    d->success[s] |= CTX_NONE;
+-
+-  return dfastate (s, d, uc, trans);
+-}
+-
+ /* Multibyte character handling sub-routines for dfaexec.  */
+ 
+ /* Consume a single byte and transit state from 's' to '*next_state'.
+-- 
+2.11.0
+

diff --git a/sys-apps/sed/sed-4.3.ebuild b/sys-apps/sed/sed-4.3-r1.ebuild
similarity index 93%
rename from sys-apps/sed/sed-4.3.ebuild
rename to sys-apps/sed/sed-4.3-r1.ebuild
index 27615d3..fcc30b0 100644
--- a/sys-apps/sed/sed-4.3.ebuild
+++ b/sys-apps/sed/sed-4.3-r1.ebuild
@@ -1,8 +1,7 @@
 # Copyright 1999-2017 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
-# $Id$
 
-EAPI=5
+EAPI="5"
 
 inherit eutils flag-o-matic toolchain-funcs
 
@@ -21,6 +20,10 @@ RDEPEND="acl? ( virtual/acl )
 DEPEND="${RDEPEND}
        nls? ( sys-devel/gettext )"
 
+PATCHES=(
+       "${FILESDIR}"/${P}-dfa-segv-{1,2,3}.patch
+)
+
 src_bootstrap_sed() {
        # make sure system-sed works #40786
        export NO_SYS_SED=""
@@ -34,6 +37,8 @@ src_bootstrap_sed() {
 }
 
 src_prepare() {
+       epatch "${PATCHES[@]}"
+
        # don't use sed before bootstrap if we have to recover a broken host sed
        src_bootstrap_sed
 }

Reply via email to