|
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