Fix endless loop in localedef.

localedef got into an endless loop in case order_start was used for
the unnamed_section twice and the first use didn't actually result
into any definition.
This commit is contained in:
Ulrich Drepper 2009-09-07 02:32:29 -07:00
parent d76da20f7f
commit 7a7e49c020
2 changed files with 35 additions and 28 deletions

View File

@ -1,5 +1,9 @@
2009-09-07 Ulrich Drepper <drepper@redhat.com>
* locale/programs/ld-collate.c (struct locale_collate_t): Add
unnamed_section_defined field.
(collate_read): Test and set unnamed_section_defined.
* posix/getconf.c (vars): Handle POSIX2_LINE_MAX in addition to
_POSIX2_LINE_MAX.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1995-2003, 2005-2007, 2008 Free Software Foundation, Inc.
/* Copyright (C) 1995-2003, 2005-2008, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.org>, 1995.
@ -203,6 +203,8 @@ struct locale_collate_t
struct section_list *current_section;
/* There always can be an unnamed section. */
struct section_list unnamed_section;
/* Flag whether the unnamed section has been defined. */
bool unnamed_section_defined;
/* To make handling of errors easier we have another section. */
struct section_list error_section;
/* Sometimes we are defining the values for collating symbols before
@ -634,7 +636,7 @@ find_element (struct linereader *ldfile, struct locale_collate_t *collate,
if (find_entry (&collate->seq_table, str, len, &result) != 0)
{
/* Nope, not define yet. So we see whether it is a
collation symbol. */
collation symbol. */
void *ptr;
if (find_entry (&collate->sym_table, str, len, &ptr) == 0)
@ -788,7 +790,7 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
if (*cp == '<')
{
/* Ahh, it's a bsymbol or an UCS4 value. If it's
the latter we have to unify the name. */
the latter we have to unify the name. */
const char *startp = ++cp;
size_t len;
@ -1302,8 +1304,8 @@ order for `%.*s' already defined at %s:%Zu"),
else
{
/* Determine the range. To do so we have to determine the
common prefix of the both names and then the numeric
values of both ends. */
common prefix of the both names and then the numeric
values of both ends. */
size_t lenfrom = strlen (startp->name);
size_t lento = strlen (endp->name);
char buf[lento + 1];
@ -2222,14 +2224,14 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
else
{
/* The entries in the list are sorted by length and then
alphabetically. This is the order in which we will add the
elements to the collation table. This allows simply walking
alphabetically. This is the order in which we will add the
elements to the collation table. This allows simply walking
the table in sequence and stopping at the first matching
entry. Since the longer sequences are coming first in the
list they have the possibility to match first, just as it
has to be. In the worst case we are walking to the end of
the list where we put, if no singlebyte sequence is defined
in the locale definition, the weights for UNDEFINED.
entry. Since the longer sequences are coming first in the
list they have the possibility to match first, just as it
has to be. In the worst case we are walking to the end of
the list where we put, if no singlebyte sequence is defined
in the locale definition, the weights for UNDEFINED.
To reduce the length of the search list we compress them a bit.
This happens by collecting sequences of consecutive byte
@ -2297,7 +2299,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
obstack_1grow_fast (&extrapool, curp->mbs[i]);
/* Now find the end of the consecutive sequence and
add all the indeces in the indirect pool. */
add all the indeces in the indirect pool. */
do
{
weightidx = output_weight (&weightpool, collate, curp);
@ -2312,7 +2314,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
obstack_int32_grow (&indirectpool, weightidx);
/* And add the end byte sequence. Without length this
time. */
time. */
for (i = 1; i < curp->nmbs; ++i)
obstack_1grow_fast (&extrapool, curp->mbs[i]);
}
@ -2356,7 +2358,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
& (__alignof__ (int32_t) - 1)) == 0);
/* If the final entry in the list is not a single character we
add an UNDEFINED entry here. */
add an UNDEFINED entry here. */
if (lastp->nmbs != 1)
{
int added = ((sizeof (int32_t) + 1 + 1 + __alignof__ (int32_t) - 1)
@ -3293,7 +3295,7 @@ error while adding equivalent collating symbol"));
else
{
/* One should not be allowed to open the same
section twice. */
section twice. */
if (sp->first != NULL)
lr_error (ldfile, _("\
%s: multiple order definitions for section `%s'"),
@ -3349,7 +3351,7 @@ error while adding equivalent collating symbol"));
section. */
collate->current_section = &collate->unnamed_section;
if (collate->unnamed_section.first != NULL)
if (collate->unnamed_section_defined)
lr_error (ldfile, _("\
%s: multiple order definitions for unnamed section"),
"LC_COLLATE");
@ -3359,6 +3361,7 @@ error while adding equivalent collating symbol"));
the collate->sections list. */
collate->unnamed_section.next = collate->sections;
collate->sections = &collate->unnamed_section;
collate->unnamed_section_defined = true;
}
}
@ -3579,9 +3582,9 @@ error while adding equivalent collating symbol"));
else
{
/* This is bad. The section after which we have to
reorder does not exist. Therefore we cannot
process the whole rest of this reorder
specification. */
reorder does not exist. Therefore we cannot
process the whole rest of this reorder
specification. */
lr_error (ldfile, _("%s: section `%.*s' not known"),
"LC_COLLATE", (int) arg->val.str.lenmb,
arg->val.str.startmb);
@ -3657,9 +3660,9 @@ error while adding equivalent collating symbol"));
if (state == 0)
{
/* We are outside an `order_start' region. This means
we must only accept definitions of values for
collation symbols since these are purely abstract
values and don't need directions associated. */
we must only accept definitions of values for
collation symbols since these are purely abstract
values and don't need directions associated. */
void *ptr;
if (find_entry (&collate->seq_table, symstr, symlen, &ptr) == 0)
@ -3741,7 +3744,7 @@ error while adding equivalent collating symbol"));
seqp->next->last = seqp->last;
/* We also have to check whether this entry is the
first or last of a section. */
first or last of a section. */
if (seqp->section->first == seqp)
{
if (seqp->section->first == seqp->section->last)
@ -3798,7 +3801,7 @@ error while adding equivalent collating symbol"));
}
/* Process the rest of the line which might change
the collation rules. */
the collation rules. */
arg = lr_token (ldfile, charmap, result, repertoire,
verbose);
if (arg->tok != tok_eof && arg->tok != tok_eol)
@ -3810,8 +3813,8 @@ error while adding equivalent collating symbol"));
else if (was_ellipsis != tok_none)
{
/* Using the information in the `ellipsis_weight'
element and this and the last value we have to handle
the ellipsis now. */
element and this and the last value we have to handle
the ellipsis now. */
assert (state == 1);
handle_ellipsis (ldfile, symstr, symlen, was_ellipsis, charmap,
@ -3871,7 +3874,7 @@ error while adding equivalent collating symbol"));
case tok_ellipsis3: /* absolute ellipsis */
case tok_ellipsis4: /* symbolic decimal ellipsis */
/* This is the symbolic (decimal or hexadecimal) or absolute
ellipsis. */
ellipsis. */
if (was_ellipsis != tok_none)
goto err_label;