1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

Working on #830. Cope with bad conversions better - don't just memcpy but

try a crap conversion instead. Next this needs to be done to the convert_alloc
function.
Actually fixes some valgrind warnings as well - cool !
Jeremy.
(This used to be commit 6a7919f254)
This commit is contained in:
Jeremy Allison 2004-02-04 02:09:41 +00:00
parent 160d3e2a9c
commit 39f8afa866
2 changed files with 82 additions and 11 deletions

View File

@ -184,14 +184,18 @@ static size_t convert_string_internal(charset_t from, charset_t to,
}
}
if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
if (!conv_silent)
DEBUG(0,("convert_string_internal: Conversion not supported.\n"));
goto use_as_is;
return 0;
}
i_len=srclen;
o_len=destlen;
again:
retval = smb_iconv(descriptor, (char **)&inbuf, &i_len, &outbuf, &o_len);
if(retval==(size_t)-1) {
const char *reason="unknown error";
@ -227,12 +231,76 @@ static size_t convert_string_internal(charset_t from, charset_t to,
use_as_is:
/* conversion not supported, use as is */
/*
* Conversion not supported. This is actually an error, but there are so
* many misconfigured iconv systems and smb.conf's out there we can't just
* fail. Do a very bad conversion instead.... JRA.
*/
{
size_t len = MIN(srclen,destlen);
if (len)
memcpy(dest,src,len);
return len;
if (o_len == 0 || i_len == 0)
return destlen - o_len;
if (from == CH_UCS2 && to != CH_UCS2) {
/* Can't convert from ucs2 to multibyte. Just truncate this char to ascii. */
if (i_len < 2)
return destlen - o_len;
if (i_len >= 2) {
*outbuf = inbuf[0];
outbuf++;
o_len--;
inbuf += 2;
i_len -= 2;
}
if (o_len == 0 || i_len == 0)
return destlen - o_len;
/* Keep trying with the next char... */
goto again;
} else if (from != CH_UCS2 && to == CH_UCS2) {
/* Can't convert to ucs2 - just widen by adding zero. */
if (o_len < 2)
return destlen;
outbuf[0] = inbuf[0];
outbuf[1] = '\0';
inbuf++;
i_len--;
outbuf += 2;
o_len -= 2;
if (o_len == 0 || i_len == 0)
return destlen - o_len;
/* Keep trying with the next char... */
goto again;
} else if (from != CH_UCS2 && to != CH_UCS2) {
/* Failed multibyte to multibyte. Just copy 1 char and
try again. */
outbuf[0] = inbuf[0];
inbuf++;
i_len--;
outbuf++;
o_len--;
if (o_len == 0 || i_len == 0)
return destlen - o_len;
/* Keep trying with the next char... */
goto again;
} else {
/* Keep compiler happy.... */
return destlen - o_len;
}
}
}
@ -241,9 +309,9 @@ static size_t convert_string_internal(charset_t from, charset_t to,
* Fast path version - handles ASCII first.
*
* @param src pointer to source string (multibyte or singlebyte)
* @param srclen length of the source string in bytes
* @param srclen length of the source string in bytes, or -1 for nul terminated.
* @param dest pointer to destination string (multibyte or singlebyte)
* @param destlen maximal length allowed for string
* @param destlen maximal length allowed for string - *NEVER* -1.
* @returns the number of bytes occupied in the destination
*
* Ensure the srclen contains the terminating zero.
@ -257,11 +325,15 @@ size_t convert_string(charset_t from, charset_t to,
void *dest, size_t destlen)
{
/*
* NB. We deliberately don't do a strlen here is srclen == -1.
* NB. We deliberately don't do a strlen here if srclen == -1.
* This is very expensive over millions of calls and is taken
* care of in the slow path in convert_string_internal. JRA.
*/
#ifdef DEVELOPER
SMB_ASSERT(destlen != (size_t)-1);
#endif
if (srclen == 0)
return 0;
@ -302,7 +374,7 @@ size_t convert_string(charset_t from, charset_t to,
unsigned char lastp;
/* If all characters are ascii, fast path here. */
while ((slen >= 2) && dlen) {
while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
*q++ = *p;
if (slen != (size_t)-1) {

View File

@ -589,4 +589,3 @@ toobig:
errno = E2BIG;
return -1;
}