lalr: fix segmentation violation

The "includes" relation [DeRemer 1982] is between gotos, so of course,
for a given goto, there cannot be more that ngotos (number of gotos)
images.  But we manipulate the set of images of a goto as a list,
without checking that an image was not already introduced.  So we can
"register" way more images than ngotos, leading to a crash (heap
buffer overflow).

Reported by wcventure.
http://lists.gnu.org/archive/html/bug-bison/2019-03/msg00007.html

For the records, this bug is present in the first committed version of
Bison.

* src/lalr.c (build_relations): Don't insert the same goto several
times.
* tests/sets.at (Build Relations): New.
This commit is contained in:
Akim Demaille
2019-03-29 22:37:51 +01:00
parent d332ff3c77
commit bbf37f2534
3 changed files with 58 additions and 2 deletions

View File

@@ -271,7 +271,7 @@ build_relations (void)
int nedges = 0;
for (rule **rulep = derives[var - ntokens]; *rulep; ++rulep)
{
rule const* r = *rulep;
rule const *r = *rulep;
state *s = states[src];
path[0] = s->number;
@@ -295,7 +295,19 @@ build_relations (void)
for (int p = length - 2; 0 <= p && ISVAR (r->rhs[p]); --p)
{
symbol_number sym = item_number_as_symbol_number (r->rhs[p]);
edge[nedges++] = map_goto (path[p], sym);
goto_number g = map_goto (path[p], sym);
/* Insert G if not already in EDGE.
FIXME: linear search. A bitset instead? */
{
bool found = false;
for (int j = 0; !found && j < nedges; ++j)
found = edge[j] == g;
if (!found)
{
assert (nedges < ngotos + 1);
edge[nedges++] = map_goto (path[p], sym);
}
}
if (!nullable[sym - ntokens])
break;
}