|
9 | 9 | *
|
10 | 10 | *
|
11 | 11 | * IDENTIFICATION
|
12 |
| - * $Header: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v 1.43 2002/09/04 20:31:28 momjian Exp $ |
| 12 | + * $Header: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v 1.43.2.1 2007/09/22 05:36:20 tgl Exp $ |
13 | 13 | *
|
14 | 14 | *-------------------------------------------------------------------------
|
15 | 15 | */
|
@@ -682,27 +682,32 @@ translate(PG_FUNCTION_ARGS)
|
682 | 682 | tolen,
|
683 | 683 | retlen,
|
684 | 684 | i;
|
685 |
| - |
686 |
| - int str_len; |
687 |
| - int estimate_len; |
| 685 | + int worst_len; |
688 | 686 | int len;
|
689 | 687 | int source_len;
|
690 | 688 | int from_index;
|
691 | 689 |
|
692 |
| - if ((m = VARSIZE(string) - VARHDRSZ) <= 0) |
| 690 | + m = VARSIZE(string) - VARHDRSZ; |
| 691 | + if (m <= 0) |
693 | 692 | PG_RETURN_TEXT_P(string);
|
| 693 | + source = VARDATA(string); |
694 | 694 |
|
695 | 695 | fromlen = VARSIZE(from) - VARHDRSZ;
|
696 | 696 | from_ptr = VARDATA(from);
|
697 | 697 | tolen = VARSIZE(to) - VARHDRSZ;
|
698 | 698 | to_ptr = VARDATA(to);
|
699 | 699 |
|
700 |
| - str_len = VARSIZE(string); |
701 |
| - estimate_len = (tolen * 1.0 / fromlen + 0.5) * str_len; |
702 |
| - estimate_len = estimate_len > str_len ? estimate_len : str_len; |
703 |
| - result = (text *) palloc(estimate_len); |
| 700 | + /* |
| 701 | + * The worst-case expansion is to substitute a max-length character for |
| 702 | + * a single-byte character at each position of the string. |
| 703 | + */ |
| 704 | + worst_len = pg_database_encoding_max_length() * m; |
| 705 | + |
| 706 | + /* check for integer overflow */ |
| 707 | + if (worst_len / pg_database_encoding_max_length() != m) |
| 708 | + elog(ERROR, "requested length too large"); |
704 | 709 |
|
705 |
| - source = VARDATA(string); |
| 710 | + result = (text *) palloc(worst_len + VARHDRSZ); |
706 | 711 | target = VARDATA(result);
|
707 | 712 | retlen = 0;
|
708 | 713 |
|
|
0 commit comments