Fix memory allocation problems on the utf-16 versions of collating function
control routines. (CVS 2817)

FossilOrigin-Name: ad292e27336b8c5afc0acdf111944a456bd23c32
diff --git a/src/main.c b/src/main.c
index ff5bc08..5117200 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.308 2005/12/12 06:53:04 danielk1977 Exp $
+** $Id: main.c,v 1.309 2005/12/15 03:04:10 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -35,19 +35,6 @@
 static sqlite3 *pDbList = 0;
 #endif
 
-#ifndef SQLITE_OMIT_UTF16
-/* 
-** Return the transient sqlite3_value object used for encoding conversions
-** during SQL compilation.
-*/
-sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){
-  if( !db->pValue ){
-    db->pValue = sqlite3ValueNew();
-  }
-  return db->pValue;
-}
-#endif
-
 /*
 ** The version of the library
 */
@@ -182,9 +169,6 @@
 
   sqlite3HashClear(&db->aFunc);
   sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
-  if( db->pValue ){
-    sqlite3ValueFree(db->pValue);
-  }
   if( db->pErr ){
     sqlite3ValueFree(db->pErr);
   }
@@ -496,21 +480,18 @@
   void (*xFinal)(sqlite3_context*)
 ){
   int rc;
-  char const *zFunc8;
-  sqlite3_value *pTmp;
+  char *zFunc8;
 
   if( sqlite3SafetyCheck(db) ){
     return SQLITE_MISUSE;
   }
-  pTmp = sqlite3GetTransientValue(db);
-  sqlite3ValueSetStr(pTmp, -1, zFunctionName, SQLITE_UTF16NATIVE,SQLITE_STATIC);
-  zFunc8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
-
+  zFunc8 = sqlite3utf16to8(zFunctionName, -1);
   if( !zFunc8 ){
     return SQLITE_NOMEM;
   }
   rc = sqlite3_create_function(db, zFunc8, nArg, eTextRep, 
       pUserData, xFunc, xStep, xFinal);
+  sqliteFree(zFunc8);
   return rc;
 }
 #endif
@@ -958,15 +939,15 @@
   void* pCtx,
   int(*xCompare)(void*,int,const void*,int,const void*)
 ){
-  char const *zName8;
-  sqlite3_value *pTmp;
+  char *zName8;
+  int rc;
   if( sqlite3SafetyCheck(db) ){
     return SQLITE_MISUSE;
   }
-  pTmp = sqlite3GetTransientValue(db);
-  sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF16NATIVE, SQLITE_STATIC);
-  zName8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
-  return sqlite3_create_collation(db, zName8, enc, pCtx, xCompare);
+  zName8 = sqlite3utf16to8(zName, -1);
+  rc = sqlite3_create_collation(db, zName8, enc, pCtx, xCompare);
+  sqliteFree(zName8);
+  return rc;
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
diff --git a/src/prepare.c b/src/prepare.c
index c702fb9..ca00049 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -13,7 +13,7 @@
 ** interface, and routines that contribute to loading the database schema
 ** from disk.
 **
-** $Id: prepare.c,v 1.8 2005/12/12 06:53:04 danielk1977 Exp $
+** $Id: prepare.c,v 1.9 2005/12/15 03:04:11 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -515,17 +515,14 @@
   ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
   ** tricky bit is figuring out the pointer to return in *pzTail.
   */
-  char const *zSql8 = 0;
-  char const *zTail8 = 0;
+  char *zSql8 = 0;
+  char *zTail8 = 0;
   int rc;
-  sqlite3_value *pTmp;
 
   if( sqlite3SafetyCheck(db) ){
     return SQLITE_MISUSE;
   }
-  pTmp = sqlite3GetTransientValue(db);
-  sqlite3ValueSetStr(pTmp, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
-  zSql8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
+  zSql8 = sqlite3utf16to8(zSql, nBytes);
   if( !zSql8 ){
     sqlite3Error(db, SQLITE_NOMEM, 0);
     return SQLITE_NOMEM;
@@ -541,7 +538,7 @@
     int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8);
     *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed);
   }
- 
+  sqliteFree(zSql8); 
   return rc;
 }
 #endif /* SQLITE_OMIT_UTF16 */
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 2ce46e0..aa1bf3e 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.434 2005/12/12 06:53:05 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.435 2005/12/15 03:04:11 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -443,7 +443,6 @@
   void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
   void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
   void *pCollNeededArg;
-  sqlite3_value *pValue;        /* Value used for transient conversions */
   sqlite3_value *pErr;          /* Most recent error message */
   char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */
   char *zErrMsg16;              /* Most recent error message (UTF-16 encoded) */
@@ -1645,7 +1644,7 @@
 void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*));
 void sqlite3ValueFree(sqlite3_value*);
 sqlite3_value *sqlite3ValueNew(void);
-sqlite3_value *sqlite3GetTransientValue(sqlite3*db);
+char *sqlite3utf16to8(const void*, int);
 int sqlite3ValueFromExpr(Expr *, u8, u8, sqlite3_value **);
 void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
 extern const unsigned char sqlite3UpperToLower[];
diff --git a/src/utf.c b/src/utf.c
index f9c944f..3387a57 100644
--- a/src/utf.c
+++ b/src/utf.c
@@ -12,7 +12,7 @@
 ** This file contains routines used to translate between UTF-8, 
 ** UTF-16, UTF-16BE, and UTF-16LE.
 **
-** $Id: utf.c,v 1.33 2005/12/09 20:02:06 drh Exp $
+** $Id: utf.c,v 1.34 2005/12/15 03:04:11 drh Exp $
 **
 ** Notes on UTF-8:
 **
@@ -451,6 +451,21 @@
 
 #ifndef SQLITE_OMIT_UTF16
 /*
+** Convert a UTF-16 string in the native encoding into a UTF-8 string.
+** Memory to hold the UTF-8 string is obtained from malloc and must be
+** freed by the calling function.
+**
+** NULL is returned if there is an allocation error.
+*/
+char *sqlite3utf16to8(const void *z, int nByte){
+  Mem m;
+  memset(&m, 0, sizeof(m));
+  sqlite3VdbeMemSetStr(&m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC);
+  sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8);
+  return m.z;
+}
+
+/*
 ** pZ is a UTF-16 encoded unicode string. If nChar is less than zero,
 ** return the number of bytes up to (but not including), the first pair
 ** of consecutive 0x00 bytes in pZ. If nChar is not less than zero,