diff options
-rw-r--r-- | lib/util/charset/charcnv.c | 90 |
1 files changed, 57 insertions, 33 deletions
diff --git a/lib/util/charset/charcnv.c b/lib/util/charset/charcnv.c index 5489cf7391..88f464c2c2 100644 --- a/lib/util/charset/charcnv.c +++ b/lib/util/charset/charcnv.c @@ -122,14 +122,15 @@ convert: * @param dest pointer to destination string (multibyte or singlebyte) * @param destlen maximal length allowed for string * @returns the number of bytes occupied in the destination + * on error, returns -1, and sets errno **/ -_PUBLIC_ bool convert_string_convenience(struct smb_iconv_convenience *ic, - charset_t from, charset_t to, - void const *src, size_t srclen, - void *dest, size_t destlen, size_t *converted_size) +_PUBLIC_ ssize_t convert_string_error(struct smb_iconv_convenience *ic, + charset_t from, charset_t to, + void const *src, size_t srclen, + void *dest, size_t destlen, size_t *converted_size) { size_t i_len, o_len; - size_t retval; + ssize_t retval; const char* inbuf = (const char*)src; char* outbuf = (char*)dest; smb_iconv_t descriptor; @@ -138,45 +139,68 @@ _PUBLIC_ bool convert_string_convenience(struct smb_iconv_convenience *ic, srclen = strlen(inbuf)+1; descriptor = get_conv_handle(ic, from, to); - if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { - /* conversion not supported, use as is */ - size_t len = MIN(srclen,destlen); - memcpy(dest,src,len); - *converted_size = len; - return true; + if (converted_size) { + *converted_size = 0; + } + errno = EINVAL; + return -1; } i_len=srclen; o_len=destlen; + retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len); + + if (converted_size != NULL) + *converted_size = destlen-o_len; + return retval; +} + + +/** + * Convert string from one encoding to another, making error checking etc + * + * @param src pointer to source string (multibyte or singlebyte) + * @param srclen length of the source string in bytes + * @param dest pointer to destination string (multibyte or singlebyte) + * @param destlen maximal length allowed for string + * @returns the number of bytes occupied in the destination + **/ +_PUBLIC_ bool convert_string_convenience(struct smb_iconv_convenience *ic, + charset_t from, charset_t to, + void const *src, size_t srclen, + void *dest, size_t destlen, size_t *converted_size) +{ + ssize_t retval; + + retval = convert_string_error(ic, from, to, src, srclen, dest, destlen, converted_size); if(retval==(size_t)-1) { const char *reason; switch(errno) { - case EINVAL: - reason="Incomplete multibyte sequence"; - return false; - case E2BIG: - reason="No more room"; - if (from == CH_UNIX) { - DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d - '%s'\n", - charset_name(ic, from), charset_name(ic, to), - (int)srclen, (int)destlen, - (const char *)src)); - } else { - DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d\n", - charset_name(ic, from), charset_name(ic, to), - (int)srclen, (int)destlen)); - } - return false; - case EILSEQ: - reason="Illegal multibyte sequence"; - return false; + case EINVAL: + reason="Incomplete multibyte sequence"; + return false; + case E2BIG: + reason="No more room"; + if (from == CH_UNIX) { + DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d - '%s'\n", + charset_name(ic, from), charset_name(ic, to), + (int)srclen, (int)destlen, + (const char *)src)); + } else { + DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d\n", + charset_name(ic, from), charset_name(ic, to), + (int)srclen, (int)destlen)); + } + return false; + case EILSEQ: + reason="Illegal multibyte sequence"; + return false; + default: + return false; } - /* smb_panic(reason); */ } - if (converted_size != NULL) - *converted_size = destlen-o_len; return true; } |