mirror of
https://github.com/postgres/postgres.git
synced 2025-05-05 09:19:17 +03:00
Fix bogus calculation of potential output string length in translate().
This commit is contained in:
parent
d5e6f4f828
commit
a9f08b41ac
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.67.2.1 2007/02/08 20:33:54 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.67.2.2 2007/09/22 05:35:52 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1153,27 +1153,34 @@ translate(PG_FUNCTION_ARGS)
|
|||||||
tolen,
|
tolen,
|
||||||
retlen,
|
retlen,
|
||||||
i;
|
i;
|
||||||
|
int worst_len;
|
||||||
int str_len;
|
|
||||||
int estimate_len;
|
|
||||||
int len;
|
int len;
|
||||||
int source_len;
|
int source_len;
|
||||||
int from_index;
|
int from_index;
|
||||||
|
|
||||||
if ((m = VARSIZE(string) - VARHDRSZ) <= 0)
|
m = VARSIZE(string) - VARHDRSZ;
|
||||||
|
if (m <= 0)
|
||||||
PG_RETURN_TEXT_P(string);
|
PG_RETURN_TEXT_P(string);
|
||||||
|
source = VARDATA(string);
|
||||||
|
|
||||||
fromlen = VARSIZE(from) - VARHDRSZ;
|
fromlen = VARSIZE(from) - VARHDRSZ;
|
||||||
from_ptr = VARDATA(from);
|
from_ptr = VARDATA(from);
|
||||||
tolen = VARSIZE(to) - VARHDRSZ;
|
tolen = VARSIZE(to) - VARHDRSZ;
|
||||||
to_ptr = VARDATA(to);
|
to_ptr = VARDATA(to);
|
||||||
|
|
||||||
str_len = VARSIZE(string);
|
/*
|
||||||
estimate_len = (tolen * 1.0 / fromlen + 0.5) * str_len;
|
* The worst-case expansion is to substitute a max-length character for
|
||||||
estimate_len = estimate_len > str_len ? estimate_len : str_len;
|
* a single-byte character at each position of the string.
|
||||||
result = (text *) palloc(estimate_len);
|
*/
|
||||||
|
worst_len = pg_database_encoding_max_length() * m;
|
||||||
|
|
||||||
source = VARDATA(string);
|
/* 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(worst_len + VARHDRSZ);
|
||||||
target = VARDATA(result);
|
target = VARDATA(result);
|
||||||
retlen = 0;
|
retlen = 0;
|
||||||
|
|
||||||
@ -1226,9 +1233,9 @@ translate(PG_FUNCTION_ARGS)
|
|||||||
VARATT_SIZEP(result) = retlen + VARHDRSZ;
|
VARATT_SIZEP(result) = retlen + VARHDRSZ;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There may be some wasted space in the result if deletions occurred, but
|
* The function result is probably much bigger than needed, if we're
|
||||||
* it's not worth reallocating it; the function result probably won't live
|
* using a multibyte encoding, but it's not worth reallocating it;
|
||||||
* long anyway.
|
* the result probably won't live long anyway.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PG_RETURN_TEXT_P(result);
|
PG_RETURN_TEXT_P(result);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user