1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-25 17:57:42 +03:00

s3-charcnv Add convert_string_error()

This function returns errors rather than printing them.

Andrew Bartlett
This commit is contained in:
Andrew Bartlett 2011-03-25 09:15:06 +11:00 committed by Andrew Tridgell
parent 2643a7ba6b
commit 64258a300f
2 changed files with 75 additions and 18 deletions

View File

@ -416,6 +416,10 @@ void init_iconv(void);
size_t convert_string(charset_t from, charset_t to,
void const *src, size_t srclen,
void *dest, size_t destlen);
size_t convert_string_error(charset_t from, charset_t to,
void const *src, size_t srclen,
void *dest, size_t destlen,
size_t *converted_size);
size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen);
char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s);
char *strupper_talloc(TALLOC_CTX *ctx, const char *s);

View File

@ -96,7 +96,7 @@ void init_iconv(void)
static size_t convert_string_internal(charset_t from, charset_t to,
void const *src, size_t srclen,
void *dest, size_t destlen)
void *dest, size_t destlen, size_t *converted_size)
{
size_t i_len, o_len;
size_t retval;
@ -181,9 +181,10 @@ static size_t convert_string_internal(charset_t from, charset_t to,
* Don't change unless you really know what you are doing. JRA.
**/
size_t convert_string(charset_t from, charset_t to,
void const *src, size_t srclen,
void *dest, size_t destlen)
size_t convert_string_error(charset_t from, charset_t to,
void const *src, size_t srclen,
void *dest, size_t destlen,
size_t *converted_size)
{
/*
* NB. We deliberately don't do a strlen here if srclen == -1.
@ -195,6 +196,10 @@ size_t convert_string(charset_t from, charset_t to,
SMB_ASSERT(destlen != (size_t)-1);
#endif
if (converted_size) {
*converted_size = 0;
}
if (srclen == 0)
return 0;
@ -221,11 +226,11 @@ size_t convert_string(charset_t from, charset_t to,
#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
goto general_case;
#else
size_t ret = convert_string_internal(from, to, p, slen, q, dlen);
if (ret == (size_t)-1) {
return ret;
size_t ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
if (converted_size) {
*converted_size += retval;
}
return retval + ret;
return ret;
#endif
}
}
@ -261,11 +266,11 @@ size_t convert_string(charset_t from, charset_t to,
#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
goto general_case;
#else
size_t ret = convert_string_internal(from, to, p, slen, q, dlen);
if (ret == (size_t)-1) {
return ret;
size_t ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
if (converted_size) {
*converted_size += retval;
}
return retval + ret;
return ret;
#endif
}
}
@ -301,30 +306,78 @@ size_t convert_string(charset_t from, charset_t to,
#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
goto general_case;
#else
size_t ret = convert_string_internal(from, to, p, slen, q, dlen);
if (ret == (size_t)-1) {
return ret;
size_t ret = convert_string_internal(from, to, p, slen, q, dlen, converted_size);
if (converted_size) {
*converted_size += retval;
}
return retval + ret;
return ret;
#endif
}
}
if (converted_size) {
*converted_size += retval;
}
if (!dlen) {
/* Even if we fast path we should note if we ran out of room. */
if (((slen != (size_t)-1) && slen) ||
((slen == (size_t)-1) && lastp)) {
errno = E2BIG;
return -1;
}
}
return retval;
return 0;
}
#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
general_case:
#endif
return convert_string_internal(from, to, src, srclen, dest, destlen);
return convert_string_internal(from, to, src, srclen, dest, destlen, converted_size);
}
size_t convert_string(charset_t from, charset_t to,
void const *src, size_t srclen,
void *dest, size_t destlen) {
size_t converted_size;
size_t retval = convert_string_error(from, to, src, srclen, dest, destlen, &converted_size);
if(retval==(size_t)-1) {
const char *reason="unknown error";
switch(errno) {
case EINVAL:
reason="Incomplete multibyte sequence";
DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,src));
return (size_t)-1;
case E2BIG:
{
struct smb_iconv_handle *ic;
lazy_initialize_conv();
ic = get_iconv_handle();
reason="No more room";
if (from == CH_UNIX) {
DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u - '%s'\n",
charset_name(ic, from), charset_name(ic, to),
(unsigned int)srclen, (unsigned int)destlen, (const char *)src));
} else {
DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u\n",
charset_name(ic, from), charset_name(ic, to),
(unsigned int)srclen, (unsigned int)destlen));
}
break;
}
case EILSEQ:
reason="Illegal multibyte sequence";
DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,src));
return (size_t)-1;
default:
DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason,src));
return (size_t)-1;
}
/* smb_panic(reason); */
}
return converted_size;
}
/**
* Convert between character sets, allocating a new buffer using talloc for the result.
*