Skip to content

Commit

Permalink
Fix endless loop in localedef.
Browse files Browse the repository at this point in the history
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.
(cherry picked from commit 7a7e49c)
  • Loading branch information
Ulrich Drepper authored and Petr Baudis committed Sep 18, 2009
1 parent 3615766 commit d636be3
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 28 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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.

Expand Down
59 changes: 31 additions & 28 deletions locale/programs/ld-collate.c
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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]);
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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'"),
Expand Down Expand Up @@ -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");
Expand All @@ -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;
}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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,
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit d636be3

Please sign in to comment.