diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c index 6f8f82d84061155f6825281890b6a1e799b78844..b6b14cb922e8a29de1091236613f5b55c038907a 100644 --- a/src/backend/utils/adt/varchar.c +++ b/src/backend/utils/adt/varchar.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.39 1998/09/01 04:32:53 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.40 1998/09/25 01:46:21 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -147,7 +147,14 @@ bpchar(char *s, int32 len) if ((len == -1) || (len == VARSIZE(s))) return s; +#ifdef MULTIBYTE + /* truncate multi-byte string in a way not to break + multi-byte boundary */ + rlen = pg_mbcliplen(VARDATA(s), len - VARHDRSZ, len - VARHDRSZ); + len = rlen + VARHDRSZ; +#else rlen = len - VARHDRSZ; +#endif if (rlen > 4096) elog(ERROR, "bpchar: length of char() must be less than 4096"); @@ -367,7 +374,14 @@ varchar(char *s, int32 slen) /* only reach here if we need to truncate string... */ +#ifdef MULTIBYTE + /* truncate multi-byte string in a way not to break + multi-byte boundary */ + len = pg_mbcliplen(VARDATA(s), slen - VARHDRSZ, slen - VARHDRSZ); + slen = len + VARHDRSZ; +#else len = slen - VARHDRSZ; +#endif if (len > 4096) elog(ERROR, "varchar: length of varchar() must be less than 4096"); diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c index 2e0a446de20b77a202b5f5b6d4f2ebe5d9435113..e359a53df3d4350b2c673d52f39a00daf6dc7548 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.3 1998/09/01 04:33:22 momjian Exp $ */ + * $Id: mbutils.c,v 1.4 1998/09/25 01:46:23 momjian Exp $ */ #include <stdio.h> #include <string.h> @@ -201,6 +201,34 @@ pg_mbstrlen_with_len(const unsigned char *mbstr, int limit) return (len); } +/* + * returns the length of a multi-byte string + * (not necessarily NULL terminated) + * that is not longer than limit. + * this function does not break multi-byte word boundary. + */ +int +pg_mbcliplen(const unsigned char *mbstr, int len, int limit) +{ + int clen = 0; + int l; + + while (*mbstr && len > 0) + { + l = pg_mblen(mbstr); + if ((clen + l) > limit) { + break; + } + clen += l; + if (clen == limit) { + break; + } + len -= l; + mbstr += l; + } + return (clen); +} + /* * fuctions for utils/init */ diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h index 5d7c2458dda1b7a228999bb8a5c4607b674ae13e..62bbe60cb1623b36311f09407200184fcc5c9335 100644 --- a/src/include/mb/pg_wchar.h +++ b/src/include/mb/pg_wchar.h @@ -1,4 +1,4 @@ -/* $Id: pg_wchar.h,v 1.4 1998/09/01 04:36:34 momjian Exp $ */ +/* $Id: pg_wchar.h,v 1.5 1998/09/25 01:46:25 momjian Exp $ */ #ifndef PG_WCHAR_H #define PG_WCHAR_H @@ -103,6 +103,7 @@ extern int pg_mule_mblen(const unsigned char *); extern int pg_mic_mblen(const unsigned char *); extern int pg_mbstrlen(const unsigned char *); extern int pg_mbstrlen_with_len(const unsigned char *, int); +extern int pg_mbcliplen(const unsigned char *, int, int); extern pg_encoding_conv_tbl *pg_get_encent_by_encoding(int); extern bool show_client_encoding(void); extern bool reset_client_encoding(void);