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