|
9 | 9 | * |
10 | 10 | * |
11 | 11 | * IDENTIFICATION |
12 | | - *$PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.72 2007/09/21 22:52:52 tgl Exp $ |
| 12 | + *$PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.73 2007/09/22 05:35:42 tgl Exp $ |
13 | 13 | * |
14 | 14 | *------------------------------------------------------------------------- |
15 | 15 | */ |
@@ -1162,30 +1162,34 @@ translate(PG_FUNCTION_ARGS) |
1162 | 1162 | tolen, |
1163 | 1163 | retlen, |
1164 | 1164 | i; |
1165 | | - |
1166 | | -intstr_len; |
1167 | | -intestimate_len; |
| 1165 | +intworst_len; |
1168 | 1166 | intlen; |
1169 | 1167 | intsource_len; |
1170 | 1168 | intfrom_index; |
1171 | 1169 |
|
1172 | 1170 | m=VARSIZE_ANY_EXHDR(string); |
1173 | | - |
1174 | 1171 | if (m <=0) |
1175 | 1172 | PG_RETURN_TEXT_P(string); |
| 1173 | +source=VARDATA_ANY(string); |
1176 | 1174 |
|
1177 | 1175 | fromlen=VARSIZE_ANY_EXHDR(from); |
1178 | 1176 | from_ptr=VARDATA_ANY(from); |
1179 | 1177 | tolen=VARSIZE_ANY_EXHDR(to); |
1180 | 1178 | to_ptr=VARDATA_ANY(to); |
1181 | 1179 |
|
1182 | | -str_len=VARSIZE_ANY_EXHDR(string); |
1183 | | -source=VARDATA_ANY(string); |
| 1180 | +/* |
| 1181 | + * The worst-case expansion is to substitute a max-length character for |
| 1182 | + * a single-byte character at each position of the string. |
| 1183 | + */ |
| 1184 | +worst_len=pg_database_encoding_max_length()*m; |
1184 | 1185 |
|
1185 | | -estimate_len= (tolen*1.0 /fromlen+0.5)*str_len; |
1186 | | -estimate_len=estimate_len>str_len ?estimate_len :str_len; |
| 1186 | +/* check for integer overflow */ |
| 1187 | +if (worst_len /pg_database_encoding_max_length()!=m) |
| 1188 | +ereport(ERROR, |
| 1189 | +(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), |
| 1190 | +errmsg("requested length too large"))); |
1187 | 1191 |
|
1188 | | -result= (text*)palloc(estimate_len+VARHDRSZ); |
| 1192 | +result= (text*)palloc(worst_len+VARHDRSZ); |
1189 | 1193 | target=VARDATA(result); |
1190 | 1194 | retlen=0; |
1191 | 1195 |
|
@@ -1238,9 +1242,9 @@ translate(PG_FUNCTION_ARGS) |
1238 | 1242 | SET_VARSIZE(result,retlen+VARHDRSZ); |
1239 | 1243 |
|
1240 | 1244 | /* |
1241 | | - *There may be some wasted space in the result ifdeletions occurred, but |
1242 | | - * it's not worth reallocating it; the function result probably won't live |
1243 | | - * long anyway. |
| 1245 | + *The function result is probably much bigger than needed, ifwe're |
| 1246 | + *using a multibyte encoding, butit's not worth reallocating it; |
| 1247 | + *the result probably won't livelong anyway. |
1244 | 1248 | */ |
1245 | 1249 |
|
1246 | 1250 | PG_RETURN_TEXT_P(result); |
|