aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-12-15 14:55:50 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-12-15 14:55:50 +0000
commitb4d64a6d489773e2f48838473ee8541249ee7dc2 (patch)
tree146a5b8cb335e0f4adadaecbf5d1b46497b212ef /src
parent5f3724dd7c6b8beb9be3030cb3262038755c88e4 (diff)
downloadpostgresql-b4d64a6d489773e2f48838473ee8541249ee7dc2.tar.gz
postgresql-b4d64a6d489773e2f48838473ee8541249ee7dc2.zip
Remove our dependencies on MB_CUR_MAX in favor of believing that
pg_database_encoding_max_length() predicts the maximum character length returned by wchar2char(). Per Hiroshi Inoue, MB_CUR_MAX isn't usable on Windows because we allow encoding = UTF8 when the locale says differently; and getting rid of it seems a good idea on general principles because it narrows our dependence on libc's locale API just a little bit more. Also install a check for overflow of the buffer size computation.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/formatting.c44
1 files changed, 34 insertions, 10 deletions
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 5496ca496fc..8c0108050c4 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------
* formatting.c
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.151 2008/12/01 17:11:18 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.152 2008/12/15 14:55:50 tgl Exp $
*
*
* Portions Copyright (c) 1999-2008, PostgreSQL Global Development Group
@@ -1461,7 +1461,14 @@ str_tolower(const char *buff, size_t nbytes)
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
{
wchar_t *workspace;
- int curr_char = 0;
+ size_t curr_char;
+ size_t result_size;
+
+ /* Overflow paranoia */
+ if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
/* Output workspace cannot have more codes than input bytes */
workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
@@ -1472,9 +1479,10 @@ str_tolower(const char *buff, size_t nbytes)
workspace[curr_char] = towlower(workspace[curr_char]);
/* Make result large enough; case change might change number of bytes */
- result = palloc(curr_char * MB_CUR_MAX + 1);
+ result_size = curr_char * pg_database_encoding_max_length() + 1;
+ result = palloc(result_size);
- wchar2char(result, workspace, curr_char * MB_CUR_MAX + 1);
+ wchar2char(result, workspace, result_size);
pfree(workspace);
}
else
@@ -1509,7 +1517,14 @@ str_toupper(const char *buff, size_t nbytes)
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
{
wchar_t *workspace;
- int curr_char = 0;
+ size_t curr_char;
+ size_t result_size;
+
+ /* Overflow paranoia */
+ if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
/* Output workspace cannot have more codes than input bytes */
workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
@@ -1520,9 +1535,10 @@ str_toupper(const char *buff, size_t nbytes)
workspace[curr_char] = towupper(workspace[curr_char]);
/* Make result large enough; case change might change number of bytes */
- result = palloc(curr_char * MB_CUR_MAX + 1);
+ result_size = curr_char * pg_database_encoding_max_length() + 1;
+ result = palloc(result_size);
- wchar2char(result, workspace, curr_char * MB_CUR_MAX + 1);
+ wchar2char(result, workspace, result_size);
pfree(workspace);
}
else
@@ -1558,7 +1574,14 @@ str_initcap(const char *buff, size_t nbytes)
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
{
wchar_t *workspace;
- int curr_char = 0;
+ size_t curr_char;
+ size_t result_size;
+
+ /* Overflow paranoia */
+ if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
/* Output workspace cannot have more codes than input bytes */
workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
@@ -1575,9 +1598,10 @@ str_initcap(const char *buff, size_t nbytes)
}
/* Make result large enough; case change might change number of bytes */
- result = palloc(curr_char * MB_CUR_MAX + 1);
+ result_size = curr_char * pg_database_encoding_max_length() + 1;
+ result = palloc(result_size);
- wchar2char(result, workspace, curr_char * MB_CUR_MAX + 1);
+ wchar2char(result, workspace, result_size);
pfree(workspace);
}
else