summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--posix/regex.c91
2 files changed, 78 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 0f78ba3c00..290599641d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2001-07-23 Ulrich Drepper <drepper@redhat.com>
+
+ * posix/regex.c: Revamp memory allocation for WCHAR functions to
+ not use too much stack.
+
2001-07-22 Ulrich Drepper <drepper@redhat.com>
* iconv/iconvconfig.c (write_output): Update comment explaining
diff --git a/posix/regex.c b/posix/regex.c
index 463f926221..759651df14 100644
--- a/posix/regex.c
+++ b/posix/regex.c
@@ -5072,16 +5072,35 @@ weak_alias (__re_search_2, re_search_2)
#endif
#ifdef WCHAR
-# define FREE_WCS_BUFFERS() \
- do { \
- FREE_VAR (string1); \
- FREE_VAR (string2); \
- FREE_VAR (mbs_offset1); \
- FREE_VAR (mbs_offset2); \
+# define MAX_ALLOCA_SIZE 2000
+
+# define FREE_WCS_BUFFERS() \
+ do { \
+ if (size1 > MAX_ALLOCA_SIZE) \
+ { \
+ free (wcs_string1); \
+ free (mbs_offset1); \
+ } \
+ else \
+ { \
+ FREE_VAR (wcs_string1); \
+ FREE_VAR (mbs_offset1); \
+ } \
+ if (size2 > MAX_ALLOCA_SIZE) \
+ { \
+ free (wcs_string2); \
+ free (mbs_offset2); \
+ } \
+ else \
+ { \
+ FREE_VAR (wcs_string2); \
+ FREE_VAR (mbs_offset2); \
+ } \
} while (0)
#endif
+
static int
PREFIX(re_search_2) (bufp, string1, size1, string2, size2, startpos, range,
regs, stop)
@@ -5156,36 +5175,72 @@ PREFIX(re_search_2) (bufp, string1, size1, string2, size2, startpos, range,
fill them with converted string. */
if (size1 != 0)
{
- wcs_string1 = REGEX_TALLOC (size1 + 1, CHAR_T);
- mbs_offset1 = REGEX_TALLOC (size1 + 1, int);
- is_binary = REGEX_TALLOC (size1 + 1, char);
+ if (size1 > MAX_ALLOCA_SIZE)
+ {
+ wcs_string1 = TALLOC (size1 + 1, CHAR_T);
+ mbs_offset1 = TALLOC (size1 + 1, int);
+ is_binary = TALLOC (size1 + 1, char);
+ }
+ else
+ {
+ wcs_string1 = REGEX_TALLOC (size1 + 1, CHAR_T);
+ mbs_offset1 = REGEX_TALLOC (size1 + 1, int);
+ is_binary = REGEX_TALLOC (size1 + 1, char);
+ }
if (!wcs_string1 || !mbs_offset1 || !is_binary)
{
- FREE_VAR (wcs_string1);
- FREE_VAR (mbs_offset1);
- FREE_VAR (is_binary);
+ if (size1 > MAX_ALLOCA_SIZE)
+ {
+ free (wcs_string1);
+ free (mbs_offset1);
+ free (is_binary);
+ }
+ else
+ {
+ FREE_VAR (wcs_string1);
+ FREE_VAR (mbs_offset1);
+ FREE_VAR (is_binary);
+ }
return -2;
}
wcs_size1 = convert_mbs_to_wcs(wcs_string1, string1, size1,
mbs_offset1, is_binary);
wcs_string1[wcs_size1] = L'\0'; /* for a sentinel */
- FREE_VAR (is_binary);
+ if (size1 > MAX_ALLOCA_SIZE)
+ free (is_binary);
+ else
+ FREE_VAR (is_binary);
}
if (size2 != 0)
{
- wcs_string2 = REGEX_TALLOC (size2 + 1, CHAR_T);
- mbs_offset2 = REGEX_TALLOC (size2 + 1, int);
- is_binary = REGEX_TALLOC (size2 + 1, char);
+ if (size2 > MAX_ALLOCA_SIZE)
+ {
+ wcs_string2 = TALLOC (size2 + 1, CHAR_T);
+ mbs_offset2 = TALLOC (size2 + 1, int);
+ is_binary = TALLOC (size2 + 1, char);
+ }
+ else
+ {
+ wcs_string2 = REGEX_TALLOC (size2 + 1, CHAR_T);
+ mbs_offset2 = REGEX_TALLOC (size2 + 1, int);
+ is_binary = REGEX_TALLOC (size2 + 1, char);
+ }
if (!wcs_string2 || !mbs_offset2 || !is_binary)
{
FREE_WCS_BUFFERS ();
- FREE_VAR (is_binary);
+ if (size2 > MAX_ALLOCA_SIZE)
+ free (is_binary);
+ else
+ FREE_VAR (is_binary);
return -2;
}
wcs_size2 = convert_mbs_to_wcs(wcs_string2, string2, size2,
mbs_offset2, is_binary);
wcs_string2[wcs_size2] = L'\0'; /* for a sentinel */
- FREE_VAR (is_binary);
+ if (size2 > MAX_ALLOCA_SIZE)
+ free (is_binary);
+ else
+ FREE_VAR (is_binary);
}
#endif /* WCHAR */