Mercurial > hg > octave-lyh > gnulib-hg
changeset 12572:b11c0a312a68
regcomp, regexec, fnmatch: avoid array bounds read error
* lib/regcomp.c (build_equiv_class): From glibc:
Use only the low 24 bits of a findidx return value as an index
into the weights array. Patch by Ulrich Drepper:
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commit;h=b7d1c5fa30
* lib/regexec.c (check_node_accept_bytes): Likewise.
* lib/fnmatch_loop.c (FCT): Likewise.
author | Ulrich Drepper <drepper@redhat.com> |
---|---|
date | Mon, 04 Jan 2010 11:18:51 +0100 |
parents | 64d47f001127 |
children | 35e0410f273a |
files | ChangeLog lib/fnmatch_loop.c lib/regcomp.c lib/regexec.c |
diffstat | 4 files changed, 30 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2010-01-04 Jim Meyering <meyering@redhat.com> + regcomp, regexec, fnmatch: avoid array bounds read error + * lib/regcomp.c (build_equiv_class): From glibc: + Use only the low 24 bits of a findidx return value as an index + into the weights array. Patch by Ulrich Drepper: + http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commit;h=b7d1c5fa30 + * lib/regexec.c (check_node_accept_bytes): Likewise. + * lib/fnmatch_loop.c (FCT): Likewise. + regcomp: skip collseq lookup when there are no rules * lib/regcomp.c (lookup_collation_sequence_value): From glibc: http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a532a41df58
--- a/lib/fnmatch_loop.c +++ b/lib/fnmatch_loop.c @@ -382,15 +382,20 @@ /* We found a table entry. Now see whether the character we are currently at has the same equivalance class value. */ - int len = weights[idx]; + int len = weights[idx & 0xffffff]; int32_t idx2; const UCHAR *np = (const UCHAR *) n; idx2 = findidx (&np); - if (idx2 != 0 && len == weights[idx2]) + if (idx2 != 0 + && (idx >> 24) == (idx2 >> 24) + && len == weights[idx2 & 0xffffff]) { int cnt = 0; + idx &= 0xffffff; + idx2 &= 0xffffff; + while (cnt < len && (weights[idx + 1 + cnt] == weights[idx2 + 1 + cnt]))
--- a/lib/regcomp.c +++ b/lib/regcomp.c @@ -3436,7 +3436,7 @@ /* Build single byte matcing table for this equivalence class. */ char_buf[1] = (unsigned char) '\0'; - len = weights[idx1]; + len = weights[idx1 & 0xffffff]; for (ch = 0; ch < SBC_MAX; ++ch) { char_buf[0] = ch; @@ -3448,11 +3448,15 @@ if (idx2 == 0) /* This isn't a valid character. */ continue; - if (len == weights[idx2]) + /* Compare only if the length matches and the collation rule + index is the same. */ + if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24)) { int cnt = 0; + while (cnt <= len && - weights[idx1 + 1 + cnt] == weights[idx2 + 1 + cnt]) + weights[(idx1 & 0xffffff) + 1 + cnt] + == weights[(idx2 & 0xffffff) + 1 + cnt]) ++cnt; if (cnt > len)
--- a/lib/regexec.c +++ b/lib/regexec.c @@ -3949,15 +3949,20 @@ _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); - idx = findidx (&cp); + int32_t idx = findidx (&cp); if (idx > 0) for (i = 0; i < cset->nequiv_classes; ++i) { int32_t equiv_class_idx = cset->equiv_classes[i]; - size_t weight_len = weights[idx]; - if (weight_len == weights[equiv_class_idx]) + size_t weight_len = weights[idx & 0xffffff]; + if (weight_len == weights[equiv_class_idx & 0xffffff] + && (idx >> 24) == (equiv_class_idx >> 24)) { Idx cnt = 0; + + idx &= 0xffffff; + equiv_class_idx &= 0xffffff; + while (cnt <= weight_len && (weights[equiv_class_idx + 1 + cnt] == weights[idx + 1 + cnt]))