|
|
29e444 |
From c1b97d6d896b1f22fdf5d28471ef7859ec840a57 Mon Sep 17 00:00:00 2001
|
|
|
29e444 |
From: Andreas Schwab <schwab@redhat.com>
|
|
|
29e444 |
Date: Wed, 1 Sep 2010 17:26:15 +0200
|
|
|
29e444 |
Subject: [PATCH] Fix handling of collating symbols in regexps
|
|
|
29e444 |
|
|
|
29e444 |
[BZ #11561]
|
|
|
29e444 |
* posix/regcomp.c (parse_bracket_exp): When looking up collating
|
|
|
29e444 |
elements compare against the byte sequence of it, not its name.
|
|
|
29e444 |
|
|
|
29e444 |
---
|
|
|
29e444 |
ChangeLog | 4 +++
|
|
|
29e444 |
posix/regcomp.c | 72 ++++++++++++++++++++----------------------------------
|
|
|
29e444 |
2 files changed, 31 insertions(+), 45 deletions(-)
|
|
|
29e444 |
|
|
|
12745e |
--- glibc-2.17-c758a686/posix/regcomp.c
|
|
|
12745e |
+++ glibc-2.17-c758a686/posix/regcomp.c
|
|
|
29e444 |
@@ -2772,40 +2772,29 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|
|
29e444 |
|
|
|
29e444 |
/* Local function for parse_bracket_exp used in _LIBC environement.
|
|
|
29e444 |
Seek the collating symbol entry correspondings to NAME.
|
|
|
29e444 |
- Return the index of the symbol in the SYMB_TABLE. */
|
|
|
29e444 |
+ Return the index of the symbol in the SYMB_TABLE,
|
|
|
29e444 |
+ or -1 if not found. */
|
|
|
29e444 |
|
|
|
29e444 |
auto inline int32_t
|
|
|
29e444 |
__attribute ((always_inline))
|
|
|
29e444 |
- seek_collating_symbol_entry (name, name_len)
|
|
|
29e444 |
- const unsigned char *name;
|
|
|
29e444 |
- size_t name_len;
|
|
|
29e444 |
+ seek_collating_symbol_entry (const unsigned char *name, size_t name_len)
|
|
|
29e444 |
{
|
|
|
29e444 |
- int32_t hash = elem_hash ((const char *) name, name_len);
|
|
|
29e444 |
- int32_t elem = hash % table_size;
|
|
|
29e444 |
- if (symb_table[2 * elem] != 0)
|
|
|
29e444 |
- {
|
|
|
29e444 |
- int32_t second = hash % (table_size - 2) + 1;
|
|
|
29e444 |
-
|
|
|
29e444 |
- do
|
|
|
29e444 |
- {
|
|
|
29e444 |
- /* First compare the hashing value. */
|
|
|
29e444 |
- if (symb_table[2 * elem] == hash
|
|
|
29e444 |
- /* Compare the length of the name. */
|
|
|
29e444 |
- && name_len == extra[symb_table[2 * elem + 1]]
|
|
|
29e444 |
- /* Compare the name. */
|
|
|
29e444 |
- && memcmp (name, &extra[symb_table[2 * elem + 1] + 1],
|
|
|
29e444 |
- name_len) == 0)
|
|
|
29e444 |
- {
|
|
|
29e444 |
- /* Yep, this is the entry. */
|
|
|
29e444 |
- break;
|
|
|
29e444 |
- }
|
|
|
29e444 |
+ int32_t elem;
|
|
|
29e444 |
|
|
|
29e444 |
- /* Next entry. */
|
|
|
29e444 |
- elem += second;
|
|
|
29e444 |
- }
|
|
|
29e444 |
- while (symb_table[2 * elem] != 0);
|
|
|
29e444 |
- }
|
|
|
29e444 |
- return elem;
|
|
|
29e444 |
+ for (elem = 0; elem < table_size; elem++)
|
|
|
29e444 |
+ if (symb_table[2 * elem] != 0)
|
|
|
29e444 |
+ {
|
|
|
29e444 |
+ int32_t idx = symb_table[2 * elem + 1];
|
|
|
29e444 |
+ /* Skip the name of collating element name. */
|
|
|
29e444 |
+ idx += 1 + extra[idx];
|
|
|
29e444 |
+ if (/* Compare the length of the name. */
|
|
|
29e444 |
+ name_len == extra[idx]
|
|
|
29e444 |
+ /* Compare the name. */
|
|
|
29e444 |
+ && memcmp (name, &extra[idx + 1], name_len) == 0)
|
|
|
29e444 |
+ /* Yep, this is the entry. */
|
|
|
29e444 |
+ return elem;
|
|
|
29e444 |
+ }
|
|
|
29e444 |
+ return -1;
|
|
|
29e444 |
}
|
|
|
29e444 |
|
|
|
29e444 |
/* Local function for parse_bracket_exp used in _LIBC environment.
|
|
|
29e444 |
@@ -2814,8 +2803,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|
|
29e444 |
|
|
|
29e444 |
auto inline unsigned int
|
|
|
29e444 |
__attribute ((always_inline))
|
|
|
29e444 |
- lookup_collation_sequence_value (br_elem)
|
|
|
29e444 |
- bracket_elem_t *br_elem;
|
|
|
29e444 |
+ lookup_collation_sequence_value (bracket_elem_t *br_elem)
|
|
|
29e444 |
{
|
|
|
29e444 |
if (br_elem->type == SB_CHAR)
|
|
|
29e444 |
{
|
|
|
29e444 |
@@ -2843,7 +2831,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|
|
29e444 |
int32_t elem, idx;
|
|
|
29e444 |
elem = seek_collating_symbol_entry (br_elem->opr.name,
|
|
|
29e444 |
sym_name_len);
|
|
|
29e444 |
- if (symb_table[2 * elem] != 0)
|
|
|
29e444 |
+ if (elem != -1)
|
|
|
29e444 |
{
|
|
|
29e444 |
/* We found the entry. */
|
|
|
29e444 |
idx = symb_table[2 * elem + 1];
|
|
|
29e444 |
@@ -2861,7 +2849,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|
|
29e444 |
/* Return the collation sequence value. */
|
|
|
29e444 |
return *(unsigned int *) (extra + idx);
|
|
|
29e444 |
}
|
|
|
29e444 |
- else if (symb_table[2 * elem] == 0 && sym_name_len == 1)
|
|
|
29e444 |
+ else if (sym_name_len == 1)
|
|
|
29e444 |
{
|
|
|
29e444 |
/* No valid character. Match it as a single byte
|
|
|
29e444 |
character. */
|
|
|
29e444 |
@@ -2883,11 +2871,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|
|
29e444 |
|
|
|
29e444 |
auto inline reg_errcode_t
|
|
|
29e444 |
__attribute ((always_inline))
|
|
|
29e444 |
- build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
|
|
|
29e444 |
- re_charset_t *mbcset;
|
|
|
29e444 |
- int *range_alloc;
|
|
|
29e444 |
- bitset_t sbcset;
|
|
|
29e444 |
- bracket_elem_t *start_elem, *end_elem;
|
|
|
29e444 |
+ build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc,
|
|
|
29e444 |
+ bracket_elem_t *start_elem, bracket_elem_t *end_elem)
|
|
|
29e444 |
{
|
|
|
29e444 |
unsigned int ch;
|
|
|
29e444 |
uint32_t start_collseq;
|
|
|
29e444 |
@@ -2966,25 +2951,22 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|
|
29e444 |
|
|
|
29e444 |
auto inline reg_errcode_t
|
|
|
29e444 |
__attribute ((always_inline))
|
|
|
29e444 |
- build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
|
|
|
29e444 |
- re_charset_t *mbcset;
|
|
|
29e444 |
- int *coll_sym_alloc;
|
|
|
29e444 |
- bitset_t sbcset;
|
|
|
29e444 |
- const unsigned char *name;
|
|
|
29e444 |
+ build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,
|
|
|
29e444 |
+ int *coll_sym_alloc, const unsigned char *name)
|
|
|
29e444 |
{
|
|
|
29e444 |
int32_t elem, idx;
|
|
|
29e444 |
size_t name_len = strlen ((const char *) name);
|
|
|
29e444 |
if (nrules != 0)
|
|
|
29e444 |
{
|
|
|
29e444 |
elem = seek_collating_symbol_entry (name, name_len);
|
|
|
29e444 |
- if (symb_table[2 * elem] != 0)
|
|
|
29e444 |
+ if (elem != -1)
|
|
|
29e444 |
{
|
|
|
29e444 |
/* We found the entry. */
|
|
|
29e444 |
idx = symb_table[2 * elem + 1];
|
|
|
29e444 |
/* Skip the name of collating element name. */
|
|
|
29e444 |
idx += 1 + extra[idx];
|
|
|
29e444 |
}
|
|
|
29e444 |
- else if (symb_table[2 * elem] == 0 && name_len == 1)
|
|
|
29e444 |
+ else if (name_len == 1)
|
|
|
29e444 |
{
|
|
|
29e444 |
/* No valid character, treat it as a normal
|
|
|
29e444 |
character. */
|