From: Tatsuo Ishii Date: Mon, 19 Nov 2001 06:48:39 +0000 (+0000) Subject: Fix nasty bugs in pg_convert() and pg_convert2(). X-Git-Tag: REL9_0_0~19037 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=5590d5fe99d88c1a9d47852e6be36aa590401f01;p=pg-rex%2Fsyncrep.git 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 --- 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);