diff options
author | Ulrich Drepper <drepper@gmail.com> | 2011-05-28 17:14:30 -0400 |
---|---|---|
committer | Ulrich Drepper <drepper@gmail.com> | 2011-05-28 17:14:30 -0400 |
commit | 8887a920a4b81a500f54893250085e0d1a52cf9a (patch) | |
tree | 94355b4c7eefa011600c53ea0dcaaa8b152eacb6 /posix/regex_internal.c | |
parent | 4f031072a5055abd83717820b59efdaa463d5853 (diff) | |
download | glibc-8887a920a4b81a500f54893250085e0d1a52cf9a.tar.gz glibc-8887a920a4b81a500f54893250085e0d1a52cf9a.tar.xz glibc-8887a920a4b81a500f54893250085e0d1a52cf9a.zip |
Fix unnecessary overallocation due to incomplete character
When incomplete characters are found at the end of a string the code ran amok and allocated lots of memory. Stricter limits are now in place.
Diffstat (limited to 'posix/regex_internal.c')
-rw-r--r-- | posix/regex_internal.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/posix/regex_internal.c b/posix/regex_internal.c index 8183a29bf6..285ae3b38e 100644 --- a/posix/regex_internal.c +++ b/posix/regex_internal.c @@ -237,13 +237,8 @@ build_wcs_buffer (re_string_t *pstr) else p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx; mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); - if (BE (mbclen == (size_t) -2, 0)) - { - /* The buffer doesn't have enough space, finish to build. */ - pstr->cur_state = prev_st; - break; - } - else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0)) + if (BE (mbclen == (size_t) -1 || mbclen == 0 + || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len), 0)) { /* We treat these cases as a singlebyte character. */ mbclen = 1; @@ -252,6 +247,12 @@ build_wcs_buffer (re_string_t *pstr) wc = pstr->trans[wc]; pstr->cur_state = prev_st; } + else if (BE (mbclen == (size_t) -2, 0)) + { + /* The buffer doesn't have enough space, finish to build. */ + pstr->cur_state = prev_st; + break; + } /* Write wide character and padding. */ pstr->wcs[byte_idx++] = wc; @@ -334,9 +335,11 @@ build_wcs_upper_buffer (re_string_t *pstr) for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) pstr->wcs[byte_idx++] = WEOF; } - else if (mbclen == (size_t) -1 || mbclen == 0) + else if (mbclen == (size_t) -1 || mbclen == 0 + || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len)) { - /* It is an invalid character or '\0'. Just use the byte. */ + /* It is an invalid character, an incomplete character + at the end of the string, or '\0'. Just use the byte. */ int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; pstr->mbs[byte_idx] = ch; /* And also cast it to wide char. */ @@ -449,7 +452,8 @@ build_wcs_upper_buffer (re_string_t *pstr) for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) pstr->wcs[byte_idx++] = WEOF; } - else if (mbclen == (size_t) -1 || mbclen == 0) + else if (mbclen == (size_t) -1 || mbclen == 0 + || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len)) { /* It is an invalid character or '\0'. Just use the byte. */ int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx]; |