summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/oracle_compat.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-09-22 05:35:42 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-09-22 05:35:42 +0000
commitbbda96d76d6a10bbd662e4e71135b188e23a815b (patch)
tree11958e67b0e65328253c2f61fa8799319e4e7eda /src/backend/utils/adt/oracle_compat.c
parent571340a00ed58ed179a9063ef77002b34afc7aca (diff)
downloadpostgresql-bbda96d76d6a10bbd662e4e71135b188e23a815b.tar.gz
Fix bogus calculation of potential output string length in translate().
Diffstat (limited to 'src/backend/utils/adt/oracle_compat.c')
-rw-r--r--src/backend/utils/adt/oracle_compat.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c
index db8c25aa67..56fe7a607f 100644
--- a/src/backend/utils/adt/oracle_compat.c
+++ b/src/backend/utils/adt/oracle_compat.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.72 2007/09/21 22:52:52 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.73 2007/09/22 05:35:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1162,30 +1162,34 @@ translate(PG_FUNCTION_ARGS)
tolen,
retlen,
i;
-
- int str_len;
- int estimate_len;
+ int worst_len;
int len;
int source_len;
int from_index;
m = VARSIZE_ANY_EXHDR(string);
-
if (m <= 0)
PG_RETURN_TEXT_P(string);
+ source = VARDATA_ANY(string);
fromlen = VARSIZE_ANY_EXHDR(from);
from_ptr = VARDATA_ANY(from);
tolen = VARSIZE_ANY_EXHDR(to);
to_ptr = VARDATA_ANY(to);
- str_len = VARSIZE_ANY_EXHDR(string);
- source = VARDATA_ANY(string);
+ /*
+ * The worst-case expansion is to substitute a max-length character for
+ * a single-byte character at each position of the string.
+ */
+ worst_len = pg_database_encoding_max_length() * m;
- estimate_len = (tolen * 1.0 / fromlen + 0.5) * str_len;
- estimate_len = estimate_len > str_len ? estimate_len : str_len;
+ /* check for integer overflow */
+ if (worst_len / pg_database_encoding_max_length() != m)
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("requested length too large")));
- result = (text *) palloc(estimate_len + VARHDRSZ);
+ result = (text *) palloc(worst_len + VARHDRSZ);
target = VARDATA(result);
retlen = 0;
@@ -1238,9 +1242,9 @@ translate(PG_FUNCTION_ARGS)
SET_VARSIZE(result, retlen + VARHDRSZ);
/*
- * There may be some wasted space in the result if deletions occurred, but
- * it's not worth reallocating it; the function result probably won't live
- * long anyway.
+ * The function result is probably much bigger than needed, if we're
+ * using a multibyte encoding, but it's not worth reallocating it;
+ * the result probably won't live long anyway.
*/
PG_RETURN_TEXT_P(result);