Index: src/utf.c ================================================================== --- src/utf.c +++ src/utf.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains routines used to translate between UTF-8, ** UTF-16, UTF-16BE, and UTF-16LE. ** -** $Id: utf.c,v 1.23 2004/06/22 22:04:46 drh Exp $ +** $Id: utf.c,v 1.24 2004/06/23 00:23:49 danielk1977 Exp $ ** ** Notes on UTF-8: ** ** Byte-0 Byte-1 Byte-2 Byte-3 Value ** 0xxxxxxx 00000000 00000000 0xxxxxxx @@ -259,10 +259,27 @@ *zIn++ = temp; } pMem->enc = desiredEnc; goto translate_out; } + + /* Set len to the maximum number of bytes required in the output buffer. */ + if( desiredEnc==SQLITE_UTF8 ){ + /* When converting from UTF-16, the maximum growth results from + ** translating a 2-byte character to a 3-byte UTF-8 character (i.e. + ** code-point 0xFFFC). A single byte is required for the output string + ** nul-terminator. + */ + len = (pMem->n/2) * 3 + 1; + }else{ + /* When converting from UTF-8 to UTF-16 the maximum growth is caused + ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16 + ** character. Two bytes are required in the output buffer for the + ** nul-terminator. + */ + len = pMem->n * 2 + 2; + } /* Set zIn to point at the start of the input buffer and zTerm to point 1 ** byte past the end. ** ** Variable zOut is set to point at the output buffer. This may be space @@ -269,11 +286,10 @@ ** obtained from malloc(), or Mem.zShort, if it large enough and not in ** use, or the zShort array on the stack (see above). */ zIn = pMem->z; zTerm = &zIn[pMem->n]; - len = pMem->n*2 + 2; if( len>NBFS ){ zOut = sqliteMallocRaw(len); if( !zOut ) return SQLITE_NOMEM; }else{ if( pMem->z==pMem->zShort ){ @@ -319,12 +335,12 @@ WRITE_UTF8(z, c); } WRITE_UTF8(z, 0); pMem->n = (z-zOut)-1; } - assert( pMem->n+1<=len ); } + assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len ); sqlite3VdbeMemRelease(pMem); pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short); pMem->enc = desiredEnc; if( (char *)zOut==pMem->zShort ){