diff options
author | Tatsuo Ishii <ishii@postgresql.org> | 2001-11-19 06:48:39 +0000 |
---|---|---|
committer | Tatsuo Ishii <ishii@postgresql.org> | 2001-11-19 06:48:39 +0000 |
commit | 5590d5fe99d88c1a9d47852e6be36aa590401f01 (patch) | |
tree | 7cbdd3785e263c12f750f220a93e43088aa309fa /src | |
parent | 09a2b4f4234f66c2dc89c269743ba04bf78ae8ba (diff) | |
download | postgresql-5590d5fe99d88c1a9d47852e6be36aa590401f01.tar.gz |
Fix nasty bugs in pg_convert() and pg_convert2().
o they sometimes returns a result garbage string appended.
o they do not work if client encoding is different from server
encoding
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/mb/mbutils.c | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c index 645b9f3260..f7bc6fdac3 100644 --- a/src/backend/utils/mb/mbutils.c +++ b/src/backend/utils/mb/mbutils.c @@ -3,7 +3,7 @@ * client encoding and server internal encoding. * (currently mule internal code (mic) is used) * Tatsuo Ishii - * $Id: mbutils.c,v 1.25 2001/10/25 05:49:51 momjian Exp $ + * $Id: mbutils.c,v 1.26 2001/11/19 06:48:39 ishii Exp $ */ #include "postgres.h" @@ -220,6 +220,8 @@ pg_convert(PG_FUNCTION_ARGS) from_mic_converter dest; unsigned char *result; text *retval; + unsigned char *str; + int len; if (encoding < 0) elog(ERROR, "Invalid encoding name %s", NameStr(*s)); @@ -231,14 +233,28 @@ pg_convert(PG_FUNCTION_ARGS) elog(ERROR, "Conversion from %s to %s is not possible", NameStr(*s), encoding_name); } - result = pg_do_encoding_conversion(VARDATA(string), VARSIZE(string) - VARHDRSZ, - src, dest); + /* make sure that source string is null terminated */ + len = VARSIZE(string) - VARHDRSZ; + str = palloc(len + 1); + memcpy(str, VARDATA(string), len); + *(str + len) = '\0'; + + result = pg_do_encoding_conversion(str, len, src, dest); if (result == NULL) elog(ERROR, "Encoding conversion failed"); - retval = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(result))); - if (result != (unsigned char *) VARDATA(string)) + /* build text data type structre. we cannot use textin() here, + since textin assumes that input string encoding is same as + database encoding. */ + len = strlen(result) + VARHDRSZ; + retval = palloc(len); + VARATT_SIZEP(retval) = len; + memcpy(VARDATA(retval), result, len - VARHDRSZ); + + /* free memory allocated by pg_do_encoding_conversion */ + if (result != str) pfree(result); + pfree(str); /* free memory if allocated by the toaster */ PG_FREE_IF_COPY(string, 0); @@ -263,6 +279,8 @@ pg_convert2(PG_FUNCTION_ARGS) from_mic_converter dest; unsigned char *result; text *retval; + unsigned char *str; + int len; if (src_encoding < 0) elog(ERROR, "Invalid source encoding name %s", src_encoding_name); @@ -275,14 +293,27 @@ pg_convert2(PG_FUNCTION_ARGS) src_encoding_name, dest_encoding_name); } - result = pg_do_encoding_conversion(VARDATA(string), VARSIZE(string) - VARHDRSZ, - src, dest); + /* make sure that source string is null terminated */ + len = VARSIZE(string) - VARHDRSZ; + str = palloc(len + 1); + memcpy(str, VARDATA(string), len); + *(str + len) = '\0'; + + result = pg_do_encoding_conversion(str, len, src, dest); if (result == NULL) elog(ERROR, "Encoding conversion failed"); - retval = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(result))); - if (result != (unsigned char *) VARDATA(string)) + /* build text data type structre. we cannot use textin() here, + since textin assumes that input string encoding is same as + database encoding. */ + len = strlen(result) + VARHDRSZ; + retval = palloc(len); + VARATT_SIZEP(retval) = len; + memcpy(VARDATA(retval), result, len - VARHDRSZ); + + if (result != str) pfree(result); + pfree(str); /* free memory if allocated by the toaster */ PG_FREE_IF_COPY(string, 0); |