From 5d04cd6804f6fc3b556e7c3b53fa0d7af39797c1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Aug 2004 21:35:43 +0000 Subject: [PATCH] r2114: Shameless theft of iconv commit from Samba4 to keep the two libs more in sync :-). try to cope with a wider range of UTF-16 characters when we are using an external libiconv library. Jeremy. --- source/include/charset.h | 9 ++--- source/include/smb.h | 6 +-- source/lib/charcnv.c | 10 ++--- source/lib/iconv.c | 79 ++++++++++++++++++++++++++++------------ source/modules/weird.c | 4 +- 5 files changed, 69 insertions(+), 39 deletions(-) diff --git a/source/include/charset.h b/source/include/charset.h index 7a9b12ef55..c5d03a62e8 100644 --- a/source/include/charset.h +++ b/source/include/charset.h @@ -31,9 +31,9 @@ typedef enum {CH_UCS2=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4} charset_t struct charset_functions { const char *name; - size_t (*pull)(void *, char **inbuf, size_t *inbytesleft, + size_t (*pull)(void *, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); - size_t (*push)(void *, char **inbuf, size_t *inbytesleft, + size_t (*push)(void *, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); struct charset_functions *prev, *next; }; @@ -57,7 +57,7 @@ struct charset_gap_table { * * */ #define SMB_GENERATE_CHARSET_MODULE_8_BIT_GAP(CHARSETNAME) \ -static size_t CHARSETNAME ## _push(void *cd, char **inbuf, size_t *inbytesleft, \ +static size_t CHARSETNAME ## _push(void *cd, const char **inbuf, size_t *inbytesleft, \ char **outbuf, size_t *outbytesleft) \ { \ while (*inbytesleft >= 2 && *outbytesleft >= 1) { \ @@ -97,7 +97,7 @@ static size_t CHARSETNAME ## _push(void *cd, char **inbuf, size_t *inbytesleft, return 0; \ } \ \ -static size_t CHARSETNAME ## _pull(void *cd, char **inbuf, size_t *inbytesleft, \ +static size_t CHARSETNAME ## _pull(void *cd, const char **inbuf, size_t *inbytesleft, \ char **outbuf, size_t *outbytesleft) \ { \ while (*inbytesleft >= 1 && *outbytesleft >= 2) { \ @@ -124,4 +124,3 @@ NTSTATUS charset_ ## CHARSETNAME ## _init(void) \ return smb_register_charset(& CHARSETNAME ## _functions); \ } \ - diff --git a/source/include/smb.h b/source/include/smb.h index 32dba0cf78..7317fd16b0 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -1658,11 +1658,11 @@ struct unix_error_map { /* generic iconv conversion structure */ typedef struct { - size_t (*direct)(void *cd, char **inbuf, size_t *inbytesleft, + size_t (*direct)(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); - size_t (*pull)(void *cd, char **inbuf, size_t *inbytesleft, + size_t (*pull)(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); - size_t (*push)(void *cd, char **inbuf, size_t *inbytesleft, + size_t (*push)(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); void *cd_direct, *cd_pull, *cd_push; char *from_name, *to_name; diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c index 6cbf7562b0..21d34f30cb 100644 --- a/source/lib/charcnv.c +++ b/source/lib/charcnv.c @@ -56,7 +56,7 @@ static const char *charset_name(charset_t ch) { const char *ret = NULL; - if (ch == CH_UCS2) ret = "UCS-2LE"; + if (ch == CH_UCS2) ret = "UTF-16LE"; else if (ch == CH_UNIX) ret = lp_unix_charset(); else if (ch == CH_DOS) ret = lp_dos_charset(); else if (ch == CH_DISPLAY) ret = lp_display_charset(); @@ -116,10 +116,10 @@ void init_iconv(void) /* so that charset_name() works we need to get the UNIX<->UCS2 going first */ if (!conv_handles[CH_UNIX][CH_UCS2]) - conv_handles[CH_UNIX][CH_UCS2] = smb_iconv_open("UCS-2LE", "ASCII"); + conv_handles[CH_UNIX][CH_UCS2] = smb_iconv_open(charset_name(CH_UCS2), "ASCII"); if (!conv_handles[CH_UCS2][CH_UNIX]) - conv_handles[CH_UCS2][CH_UNIX] = smb_iconv_open("ASCII", "UCS-2LE"); + conv_handles[CH_UCS2][CH_UNIX] = smb_iconv_open("ASCII", charset_name(CH_UCS2)); for (c1=0;c1direct) { return cd->direct(cd->cd_direct, - (char **)inbuf, inbytesleft, outbuf, outbytesleft); + inbuf, inbytesleft, outbuf, outbytesleft); } @@ -168,14 +175,14 @@ size_t smb_iconv(smb_iconv_t cd, bufsize = sizeof(cvtbuf); if (cd->pull(cd->cd_pull, - (char **)inbuf, inbytesleft, &bufp, &bufsize) == -1 + inbuf, inbytesleft, &bufp, &bufsize) == -1 && errno != E2BIG) return -1; bufp = cvtbuf; bufsize = sizeof(cvtbuf) - bufsize; if (cd->push(cd->cd_push, - &bufp, &bufsize, + (const char **)&bufp, &bufsize, outbuf, outbytesleft) == -1) return -1; } @@ -313,7 +320,7 @@ int smb_iconv_close (smb_iconv_t cd) multi-byte character set support for english users ***********************************************************************/ -static size_t ascii_pull(void *cd, char **inbuf, size_t *inbytesleft, +static size_t ascii_pull(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { while (*inbytesleft >= 1 && *outbytesleft >= 2) { @@ -333,7 +340,7 @@ static size_t ascii_pull(void *cd, char **inbuf, size_t *inbytesleft, return 0; } -static size_t ascii_push(void *cd, char **inbuf, size_t *inbytesleft, +static size_t ascii_push(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { int ir_count=0; @@ -360,7 +367,7 @@ static size_t ascii_push(void *cd, char **inbuf, size_t *inbytesleft, return ir_count; } -static size_t latin1_push(void *cd, char **inbuf, size_t *inbytesleft, +static size_t latin1_push(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { int ir_count=0; @@ -387,7 +394,7 @@ static size_t latin1_push(void *cd, char **inbuf, size_t *inbytesleft, return ir_count; } -static size_t ucs2hex_pull(void *cd, char **inbuf, size_t *inbytesleft, +static size_t ucs2hex_pull(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { while (*inbytesleft >= 1 && *outbytesleft >= 2) { @@ -430,7 +437,7 @@ static size_t ucs2hex_pull(void *cd, char **inbuf, size_t *inbytesleft, return 0; } -static size_t ucs2hex_push(void *cd, char **inbuf, size_t *inbytesleft, +static size_t ucs2hex_push(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { while (*inbytesleft >= 2 && *outbytesleft >= 1) { @@ -471,8 +478,32 @@ static size_t ucs2hex_push(void *cd, char **inbuf, size_t *inbytesleft, return 0; } +static size_t iconv_swab(void *cd, const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + int n; + + n = MIN(*inbytesleft, *outbytesleft); + + swab(*inbuf, *outbuf, (n&~1)); + if (n&1) { + (*outbuf)[n-1] = 0; + } + + (*inbytesleft) -= n; + (*outbytesleft) -= n; + (*inbuf) += n; + (*outbuf) += n; + + if (*inbytesleft > 0) { + errno = E2BIG; + return -1; + } + + return 0; +} -static size_t iconv_copy(void *cd, char **inbuf, size_t *inbytesleft, +static size_t iconv_copy(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { int n; @@ -494,11 +525,11 @@ static size_t iconv_copy(void *cd, char **inbuf, size_t *inbytesleft, return 0; } -static size_t utf8_pull(void *cd, char **inbuf, size_t *inbytesleft, +static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { while (*inbytesleft >= 1 && *outbytesleft >= 2) { - unsigned char *c = (unsigned char *)*inbuf; + const unsigned char *c = (const unsigned char *)*inbuf; unsigned char *uc = (unsigned char *)*outbuf; int len = 1; @@ -541,12 +572,12 @@ badseq: return -1; } -static size_t utf8_push(void *cd, char **inbuf, size_t *inbytesleft, +static size_t utf8_push(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { while (*inbytesleft >= 2 && *outbytesleft >= 1) { unsigned char *c = (unsigned char *)*outbuf; - unsigned char *uc = (unsigned char *)*inbuf; + const unsigned char *uc = (const unsigned char *)*inbuf; int len=1; if (uc[1] & 0xf8) { diff --git a/source/modules/weird.c b/source/modules/weird.c index 444853f383..3c59fd9d61 100644 --- a/source/modules/weird.c +++ b/source/modules/weird.c @@ -31,7 +31,7 @@ static struct { {0, NULL} }; -static size_t weird_pull(void *cd, char **inbuf, size_t *inbytesleft, +static size_t weird_pull(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { while (*inbytesleft >= 1 && *outbytesleft >= 2) { @@ -74,7 +74,7 @@ static size_t weird_pull(void *cd, char **inbuf, size_t *inbytesleft, return 0; } -static size_t weird_push(void *cd, char **inbuf, size_t *inbytesleft, +static size_t weird_push(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { int ir_count=0; -- 2.34.1