xref: /sqlite-3.40.0/src/test_func.c (revision bb201344)
1984bfaa4Sdrh /*
2984bfaa4Sdrh ** 2008 March 19
3984bfaa4Sdrh **
4984bfaa4Sdrh ** The author disclaims copyright to this source code.  In place of
5984bfaa4Sdrh ** a legal notice, here is a blessing:
6984bfaa4Sdrh **
7984bfaa4Sdrh **    May you do good and not evil.
8984bfaa4Sdrh **    May you find forgiveness for yourself and forgive others.
9984bfaa4Sdrh **    May you share freely, never taking more than you give.
10984bfaa4Sdrh **
11984bfaa4Sdrh *************************************************************************
12984bfaa4Sdrh ** Code for testing all sorts of SQLite interfaces.  This code
13984bfaa4Sdrh ** implements new SQL functions used by the test scripts.
14984bfaa4Sdrh */
15984bfaa4Sdrh #include "sqlite3.h"
16984bfaa4Sdrh #include "tcl.h"
17984bfaa4Sdrh #include <stdlib.h>
18984bfaa4Sdrh #include <string.h>
19984bfaa4Sdrh #include <assert.h>
20984bfaa4Sdrh 
21984bfaa4Sdrh 
22984bfaa4Sdrh /*
23984bfaa4Sdrh ** Allocate nByte bytes of space using sqlite3_malloc(). If the
24984bfaa4Sdrh ** allocation fails, call sqlite3_result_error_nomem() to notify
25984bfaa4Sdrh ** the database handle that malloc() has failed.
26984bfaa4Sdrh */
27984bfaa4Sdrh static void *testContextMalloc(sqlite3_context *context, int nByte){
28984bfaa4Sdrh   char *z = sqlite3_malloc(nByte);
29984bfaa4Sdrh   if( !z && nByte>0 ){
30984bfaa4Sdrh     sqlite3_result_error_nomem(context);
31984bfaa4Sdrh   }
32984bfaa4Sdrh   return z;
33984bfaa4Sdrh }
34984bfaa4Sdrh 
35984bfaa4Sdrh /*
36984bfaa4Sdrh ** This function generates a string of random characters.  Used for
37984bfaa4Sdrh ** generating test data.
38984bfaa4Sdrh */
39984bfaa4Sdrh static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){
40984bfaa4Sdrh   static const unsigned char zSrc[] =
41984bfaa4Sdrh      "abcdefghijklmnopqrstuvwxyz"
42984bfaa4Sdrh      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
43984bfaa4Sdrh      "0123456789"
44984bfaa4Sdrh      ".-!,:*^+=_|?/<> ";
45984bfaa4Sdrh   int iMin, iMax, n, r, i;
46984bfaa4Sdrh   unsigned char zBuf[1000];
47984bfaa4Sdrh 
48984bfaa4Sdrh   /* It used to be possible to call randstr() with any number of arguments,
49984bfaa4Sdrh   ** but now it is registered with SQLite as requiring exactly 2.
50984bfaa4Sdrh   */
51984bfaa4Sdrh   assert(argc==2);
52984bfaa4Sdrh 
53984bfaa4Sdrh   iMin = sqlite3_value_int(argv[0]);
54984bfaa4Sdrh   if( iMin<0 ) iMin = 0;
55984bfaa4Sdrh   if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1;
56984bfaa4Sdrh   iMax = sqlite3_value_int(argv[1]);
57984bfaa4Sdrh   if( iMax<iMin ) iMax = iMin;
58984bfaa4Sdrh   if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
59984bfaa4Sdrh   n = iMin;
60984bfaa4Sdrh   if( iMax>iMin ){
61984bfaa4Sdrh     sqlite3_randomness(sizeof(r), &r);
62984bfaa4Sdrh     r &= 0x7fffffff;
63984bfaa4Sdrh     n += r%(iMax + 1 - iMin);
64984bfaa4Sdrh   }
65984bfaa4Sdrh   assert( n<sizeof(zBuf) );
66984bfaa4Sdrh   sqlite3_randomness(n, zBuf);
67984bfaa4Sdrh   for(i=0; i<n; i++){
68984bfaa4Sdrh     zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
69984bfaa4Sdrh   }
70984bfaa4Sdrh   zBuf[n] = 0;
71984bfaa4Sdrh   sqlite3_result_text(context, (char*)zBuf, n, SQLITE_TRANSIENT);
72984bfaa4Sdrh }
73984bfaa4Sdrh 
74984bfaa4Sdrh /*
75984bfaa4Sdrh ** The following two SQL functions are used to test returning a text
76984bfaa4Sdrh ** result with a destructor. Function 'test_destructor' takes one argument
77984bfaa4Sdrh ** and returns the same argument interpreted as TEXT. A destructor is
78984bfaa4Sdrh ** passed with the sqlite3_result_text() call.
79984bfaa4Sdrh **
80984bfaa4Sdrh ** SQL function 'test_destructor_count' returns the number of outstanding
81984bfaa4Sdrh ** allocations made by 'test_destructor';
82984bfaa4Sdrh **
83984bfaa4Sdrh ** WARNING: Not threadsafe.
84984bfaa4Sdrh */
85984bfaa4Sdrh static int test_destructor_count_var = 0;
86984bfaa4Sdrh static void destructor(void *p){
87984bfaa4Sdrh   char *zVal = (char *)p;
88984bfaa4Sdrh   assert(zVal);
89984bfaa4Sdrh   zVal--;
90984bfaa4Sdrh   sqlite3_free(zVal);
91984bfaa4Sdrh   test_destructor_count_var--;
92984bfaa4Sdrh }
93984bfaa4Sdrh static void test_destructor(
94984bfaa4Sdrh   sqlite3_context *pCtx,
95984bfaa4Sdrh   int nArg,
96984bfaa4Sdrh   sqlite3_value **argv
97984bfaa4Sdrh ){
98984bfaa4Sdrh   char *zVal;
99984bfaa4Sdrh   int len;
100984bfaa4Sdrh 
101984bfaa4Sdrh   test_destructor_count_var++;
102984bfaa4Sdrh   assert( nArg==1 );
103984bfaa4Sdrh   if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
104984bfaa4Sdrh   len = sqlite3_value_bytes(argv[0]);
105984bfaa4Sdrh   zVal = testContextMalloc(pCtx, len+3);
106984bfaa4Sdrh   if( !zVal ){
107984bfaa4Sdrh     return;
108984bfaa4Sdrh   }
109984bfaa4Sdrh   zVal[len+1] = 0;
110984bfaa4Sdrh   zVal[len+2] = 0;
111984bfaa4Sdrh   zVal++;
112984bfaa4Sdrh   memcpy(zVal, sqlite3_value_text(argv[0]), len);
113984bfaa4Sdrh   sqlite3_result_text(pCtx, zVal, -1, destructor);
114984bfaa4Sdrh }
1152a5fc4d6Sshane #ifndef SQLITE_OMIT_UTF16
116da84ca8dSdrh static void test_destructor16(
117da84ca8dSdrh   sqlite3_context *pCtx,
118da84ca8dSdrh   int nArg,
119da84ca8dSdrh   sqlite3_value **argv
120da84ca8dSdrh ){
121da84ca8dSdrh   char *zVal;
122da84ca8dSdrh   int len;
123da84ca8dSdrh 
124da84ca8dSdrh   test_destructor_count_var++;
125da84ca8dSdrh   assert( nArg==1 );
126da84ca8dSdrh   if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
127da84ca8dSdrh   len = sqlite3_value_bytes16(argv[0]);
128da84ca8dSdrh   zVal = testContextMalloc(pCtx, len+3);
129da84ca8dSdrh   if( !zVal ){
130da84ca8dSdrh     return;
131da84ca8dSdrh   }
132da84ca8dSdrh   zVal[len+1] = 0;
133da84ca8dSdrh   zVal[len+2] = 0;
134da84ca8dSdrh   zVal++;
135da84ca8dSdrh   memcpy(zVal, sqlite3_value_text16(argv[0]), len);
136da84ca8dSdrh   sqlite3_result_text16(pCtx, zVal, -1, destructor);
137da84ca8dSdrh }
1382a5fc4d6Sshane #endif
139984bfaa4Sdrh static void test_destructor_count(
140984bfaa4Sdrh   sqlite3_context *pCtx,
141984bfaa4Sdrh   int nArg,
142984bfaa4Sdrh   sqlite3_value **argv
143984bfaa4Sdrh ){
144984bfaa4Sdrh   sqlite3_result_int(pCtx, test_destructor_count_var);
145984bfaa4Sdrh }
146984bfaa4Sdrh 
147984bfaa4Sdrh /*
148238746a6Sdanielk1977 ** The following aggregate function, test_agg_errmsg16(), takes zero
149238746a6Sdanielk1977 ** arguments. It returns the text value returned by the sqlite3_errmsg16()
150238746a6Sdanielk1977 ** API function.
151238746a6Sdanielk1977 */
152*bb201344Sshaneh #ifndef SQLITE_OMIT_BUILTIN_TEST
153238746a6Sdanielk1977 void sqlite3BeginBenignMalloc(void);
154238746a6Sdanielk1977 void sqlite3EndBenignMalloc(void);
155*bb201344Sshaneh #else
156*bb201344Sshaneh   #define sqlite3BeginBenignMalloc()
157*bb201344Sshaneh   #define sqlite3EndBenignMalloc()
158*bb201344Sshaneh #endif
159238746a6Sdanielk1977 static void test_agg_errmsg16_step(sqlite3_context *a, int b,sqlite3_value **c){
160238746a6Sdanielk1977 }
161238746a6Sdanielk1977 static void test_agg_errmsg16_final(sqlite3_context *ctx){
162257d9dc7Sdanielk1977 #ifndef SQLITE_OMIT_UTF16
163238746a6Sdanielk1977   const void *z;
164238746a6Sdanielk1977   sqlite3 * db = sqlite3_context_db_handle(ctx);
165238746a6Sdanielk1977   sqlite3_aggregate_context(ctx, 2048);
166238746a6Sdanielk1977   sqlite3BeginBenignMalloc();
167238746a6Sdanielk1977   z = sqlite3_errmsg16(db);
168238746a6Sdanielk1977   sqlite3EndBenignMalloc();
169238746a6Sdanielk1977   sqlite3_result_text16(ctx, z, -1, SQLITE_TRANSIENT);
170257d9dc7Sdanielk1977 #endif
171238746a6Sdanielk1977 }
172238746a6Sdanielk1977 
173238746a6Sdanielk1977 /*
174984bfaa4Sdrh ** Routines for testing the sqlite3_get_auxdata() and sqlite3_set_auxdata()
175984bfaa4Sdrh ** interface.
176984bfaa4Sdrh **
177984bfaa4Sdrh ** The test_auxdata() SQL function attempts to register each of its arguments
178984bfaa4Sdrh ** as auxiliary data.  If there are no prior registrations of aux data for
179984bfaa4Sdrh ** that argument (meaning the argument is not a constant or this is its first
180984bfaa4Sdrh ** call) then the result for that argument is 0.  If there is a prior
181984bfaa4Sdrh ** registration, the result for that argument is 1.  The overall result
182984bfaa4Sdrh ** is the individual argument results separated by spaces.
183984bfaa4Sdrh */
184984bfaa4Sdrh static void free_test_auxdata(void *p) {sqlite3_free(p);}
185984bfaa4Sdrh static void test_auxdata(
186984bfaa4Sdrh   sqlite3_context *pCtx,
187984bfaa4Sdrh   int nArg,
188984bfaa4Sdrh   sqlite3_value **argv
189984bfaa4Sdrh ){
190984bfaa4Sdrh   int i;
191984bfaa4Sdrh   char *zRet = testContextMalloc(pCtx, nArg*2);
192984bfaa4Sdrh   if( !zRet ) return;
193984bfaa4Sdrh   memset(zRet, 0, nArg*2);
194984bfaa4Sdrh   for(i=0; i<nArg; i++){
195984bfaa4Sdrh     char const *z = (char*)sqlite3_value_text(argv[i]);
196984bfaa4Sdrh     if( z ){
197984bfaa4Sdrh       int n;
198984bfaa4Sdrh       char *zAux = sqlite3_get_auxdata(pCtx, i);
199984bfaa4Sdrh       if( zAux ){
200984bfaa4Sdrh         zRet[i*2] = '1';
201984bfaa4Sdrh         assert( strcmp(zAux,z)==0 );
202984bfaa4Sdrh       }else {
203984bfaa4Sdrh         zRet[i*2] = '0';
204984bfaa4Sdrh       }
205984bfaa4Sdrh       n = strlen(z) + 1;
206984bfaa4Sdrh       zAux = testContextMalloc(pCtx, n);
207984bfaa4Sdrh       if( zAux ){
208984bfaa4Sdrh         memcpy(zAux, z, n);
209984bfaa4Sdrh         sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata);
210984bfaa4Sdrh       }
211984bfaa4Sdrh       zRet[i*2+1] = ' ';
212984bfaa4Sdrh     }
213984bfaa4Sdrh   }
214984bfaa4Sdrh   sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata);
215984bfaa4Sdrh }
216984bfaa4Sdrh 
217984bfaa4Sdrh /*
218984bfaa4Sdrh ** A function to test error reporting from user functions. This function
21900e087b2Sdrh ** returns a copy of its first argument as the error message.  If the
22000e087b2Sdrh ** second argument exists, it becomes the error code.
221984bfaa4Sdrh */
222984bfaa4Sdrh static void test_error(
223984bfaa4Sdrh   sqlite3_context *pCtx,
224984bfaa4Sdrh   int nArg,
225984bfaa4Sdrh   sqlite3_value **argv
226984bfaa4Sdrh ){
22700e087b2Sdrh   sqlite3_result_error(pCtx, (char*)sqlite3_value_text(argv[0]), -1);
22800e087b2Sdrh   if( nArg==2 ){
22900e087b2Sdrh     sqlite3_result_error_code(pCtx, sqlite3_value_int(argv[1]));
23000e087b2Sdrh   }
231984bfaa4Sdrh }
232984bfaa4Sdrh 
233191b54cbSdrh /*
2341a4e3162Sdrh ** Implementation of the counter(X) function.  If X is an integer
2351a4e3162Sdrh ** constant, then the first invocation will return X.  The second X+1.
2361a4e3162Sdrh ** and so forth.  Can be used (for example) to provide a sequence number
2371a4e3162Sdrh ** in a result set.
2381a4e3162Sdrh */
2391a4e3162Sdrh static void counterFunc(
2401a4e3162Sdrh   sqlite3_context *pCtx,   /* Function context */
2411a4e3162Sdrh   int nArg,                /* Number of function arguments */
2421a4e3162Sdrh   sqlite3_value **argv     /* Values for all function arguments */
2431a4e3162Sdrh ){
244a85f7e36Sdrh   int *pCounter = (int*)sqlite3_get_auxdata(pCtx, 0);
2451a4e3162Sdrh   if( pCounter==0 ){
2461a4e3162Sdrh     pCounter = sqlite3_malloc( sizeof(*pCounter) );
2471a4e3162Sdrh     if( pCounter==0 ){
2481a4e3162Sdrh       sqlite3_result_error_nomem(pCtx);
2491a4e3162Sdrh       return;
2501a4e3162Sdrh     }
2511a4e3162Sdrh     *pCounter = sqlite3_value_int(argv[0]);
2521a4e3162Sdrh     sqlite3_set_auxdata(pCtx, 0, pCounter, sqlite3_free);
2531a4e3162Sdrh   }else{
2541a4e3162Sdrh     ++*pCounter;
2551a4e3162Sdrh   }
2561a4e3162Sdrh   sqlite3_result_int(pCtx, *pCounter);
2571a4e3162Sdrh }
2581a4e3162Sdrh 
2591a4e3162Sdrh 
2601a4e3162Sdrh /*
261191b54cbSdrh ** This function takes two arguments.  It performance UTF-8/16 type
262191b54cbSdrh ** conversions on the first argument then returns a copy of the second
263191b54cbSdrh ** argument.
264191b54cbSdrh **
265191b54cbSdrh ** This function is used in cases such as the following:
266191b54cbSdrh **
267191b54cbSdrh **      SELECT test_isolation(x,x) FROM t1;
268191b54cbSdrh **
269191b54cbSdrh ** We want to verify that the type conversions that occur on the
270191b54cbSdrh ** first argument do not invalidate the second argument.
271191b54cbSdrh */
272191b54cbSdrh static void test_isolation(
273191b54cbSdrh   sqlite3_context *pCtx,
274191b54cbSdrh   int nArg,
275191b54cbSdrh   sqlite3_value **argv
276191b54cbSdrh ){
277191b54cbSdrh #ifndef SQLITE_OMIT_UTF16
278191b54cbSdrh   sqlite3_value_text16(argv[0]);
279191b54cbSdrh   sqlite3_value_text(argv[0]);
280191b54cbSdrh   sqlite3_value_text16(argv[0]);
281191b54cbSdrh   sqlite3_value_text(argv[0]);
282191b54cbSdrh #endif
283191b54cbSdrh   sqlite3_result_value(pCtx, argv[1]);
284191b54cbSdrh }
285191b54cbSdrh 
286a3460585Sdrh /*
287a3460585Sdrh ** Invoke an SQL statement recursively.  The function result is the
288a3460585Sdrh ** first column of the first row of the result set.
289a3460585Sdrh */
290a3460585Sdrh static void test_eval(
291a3460585Sdrh   sqlite3_context *pCtx,
292a3460585Sdrh   int nArg,
293a3460585Sdrh   sqlite3_value **argv
294a3460585Sdrh ){
295a3460585Sdrh   sqlite3_stmt *pStmt;
296a3460585Sdrh   int rc;
297a3460585Sdrh   sqlite3 *db = sqlite3_context_db_handle(pCtx);
298a3460585Sdrh   const char *zSql;
299a3460585Sdrh 
300a3460585Sdrh   zSql = (char*)sqlite3_value_text(argv[0]);
301a3460585Sdrh   rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
302a3460585Sdrh   if( rc==SQLITE_OK ){
303a3460585Sdrh     rc = sqlite3_step(pStmt);
304a3460585Sdrh     if( rc==SQLITE_ROW ){
305a3460585Sdrh       sqlite3_result_value(pCtx, sqlite3_column_value(pStmt, 0));
306a3460585Sdrh     }
307a3460585Sdrh     rc = sqlite3_finalize(pStmt);
308a3460585Sdrh   }
309a3460585Sdrh   if( rc ){
310a3460585Sdrh     char *zErr;
311a3460585Sdrh     assert( pStmt==0 );
312a3460585Sdrh     zErr = sqlite3_mprintf("sqlite3_prepare_v2() error: %s",sqlite3_errmsg(db));
313a3460585Sdrh     sqlite3_result_text(pCtx, zErr, -1, sqlite3_free);
314a3460585Sdrh     sqlite3_result_error_code(pCtx, rc);
315a3460585Sdrh   }
316a3460585Sdrh }
317a3460585Sdrh 
318191b54cbSdrh 
3197c95b0f3Sdrh /*
3207c95b0f3Sdrh ** convert one character from hex to binary
3217c95b0f3Sdrh */
3227c95b0f3Sdrh static int testHexChar(char c){
3237c95b0f3Sdrh   if( c>='0' && c<='9' ){
3247c95b0f3Sdrh     return c - '0';
3257c95b0f3Sdrh   }else if( c>='a' && c<='f' ){
3267c95b0f3Sdrh     return c - 'a' + 10;
3277c95b0f3Sdrh   }else if( c>='A' && c<='F' ){
3287c95b0f3Sdrh     return c - 'A' + 10;
3297c95b0f3Sdrh   }
3307c95b0f3Sdrh   return 0;
3317c95b0f3Sdrh }
3327c95b0f3Sdrh 
3337c95b0f3Sdrh /*
3347c95b0f3Sdrh ** Convert hex to binary.
3357c95b0f3Sdrh */
3367c95b0f3Sdrh static void testHexToBin(const char *zIn, char *zOut){
3377c95b0f3Sdrh   while( zIn[0] && zIn[1] ){
3387c95b0f3Sdrh     *(zOut++) = (testHexChar(zIn[0])<<4) + testHexChar(zIn[1]);
3397c95b0f3Sdrh     zIn += 2;
3407c95b0f3Sdrh   }
3417c95b0f3Sdrh }
3427c95b0f3Sdrh 
3437c95b0f3Sdrh /*
3447c95b0f3Sdrh **      hex_to_utf16be(HEX)
3457c95b0f3Sdrh **
3467c95b0f3Sdrh ** Convert the input string from HEX into binary.  Then return the
3477c95b0f3Sdrh ** result using sqlite3_result_text16le().
3487c95b0f3Sdrh */
34993a696f6Sdan #ifndef SQLITE_OMIT_UTF16
3507c95b0f3Sdrh static void testHexToUtf16be(
3517c95b0f3Sdrh   sqlite3_context *pCtx,
3527c95b0f3Sdrh   int nArg,
3537c95b0f3Sdrh   sqlite3_value **argv
3547c95b0f3Sdrh ){
3557c95b0f3Sdrh   int n;
3567c95b0f3Sdrh   const char *zIn;
3577c95b0f3Sdrh   char *zOut;
3587c95b0f3Sdrh   assert( nArg==1 );
3597c95b0f3Sdrh   n = sqlite3_value_bytes(argv[0]);
3607c95b0f3Sdrh   zIn = (const char*)sqlite3_value_text(argv[0]);
3617c95b0f3Sdrh   zOut = sqlite3_malloc( n/2 );
3627c95b0f3Sdrh   if( zOut==0 ){
3637c95b0f3Sdrh     sqlite3_result_error_nomem(pCtx);
3647c95b0f3Sdrh   }else{
3657c95b0f3Sdrh     testHexToBin(zIn, zOut);
3667c95b0f3Sdrh     sqlite3_result_text16be(pCtx, zOut, n/2, sqlite3_free);
3677c95b0f3Sdrh   }
3687c95b0f3Sdrh }
36993a696f6Sdan #endif
3707c95b0f3Sdrh 
3717c95b0f3Sdrh /*
3727c95b0f3Sdrh **      hex_to_utf8(HEX)
3737c95b0f3Sdrh **
3747c95b0f3Sdrh ** Convert the input string from HEX into binary.  Then return the
3757c95b0f3Sdrh ** result using sqlite3_result_text16le().
3767c95b0f3Sdrh */
3777c95b0f3Sdrh static void testHexToUtf8(
3787c95b0f3Sdrh   sqlite3_context *pCtx,
3797c95b0f3Sdrh   int nArg,
3807c95b0f3Sdrh   sqlite3_value **argv
3817c95b0f3Sdrh ){
3827c95b0f3Sdrh   int n;
3837c95b0f3Sdrh   const char *zIn;
3847c95b0f3Sdrh   char *zOut;
3857c95b0f3Sdrh   assert( nArg==1 );
3867c95b0f3Sdrh   n = sqlite3_value_bytes(argv[0]);
3877c95b0f3Sdrh   zIn = (const char*)sqlite3_value_text(argv[0]);
3887c95b0f3Sdrh   zOut = sqlite3_malloc( n/2 );
3897c95b0f3Sdrh   if( zOut==0 ){
3907c95b0f3Sdrh     sqlite3_result_error_nomem(pCtx);
3917c95b0f3Sdrh   }else{
3927c95b0f3Sdrh     testHexToBin(zIn, zOut);
3937c95b0f3Sdrh     sqlite3_result_text(pCtx, zOut, n/2, sqlite3_free);
3947c95b0f3Sdrh   }
3957c95b0f3Sdrh }
3967c95b0f3Sdrh 
3977c95b0f3Sdrh /*
3987c95b0f3Sdrh **      hex_to_utf16le(HEX)
3997c95b0f3Sdrh **
4007c95b0f3Sdrh ** Convert the input string from HEX into binary.  Then return the
4017c95b0f3Sdrh ** result using sqlite3_result_text16le().
4027c95b0f3Sdrh */
40393a696f6Sdan #ifndef SQLITE_OMIT_UTF16
4047c95b0f3Sdrh static void testHexToUtf16le(
4057c95b0f3Sdrh   sqlite3_context *pCtx,
4067c95b0f3Sdrh   int nArg,
4077c95b0f3Sdrh   sqlite3_value **argv
4087c95b0f3Sdrh ){
4097c95b0f3Sdrh   int n;
4107c95b0f3Sdrh   const char *zIn;
4117c95b0f3Sdrh   char *zOut;
4127c95b0f3Sdrh   assert( nArg==1 );
4137c95b0f3Sdrh   n = sqlite3_value_bytes(argv[0]);
4147c95b0f3Sdrh   zIn = (const char*)sqlite3_value_text(argv[0]);
4157c95b0f3Sdrh   zOut = sqlite3_malloc( n/2 );
4167c95b0f3Sdrh   if( zOut==0 ){
4177c95b0f3Sdrh     sqlite3_result_error_nomem(pCtx);
4187c95b0f3Sdrh   }else{
4197c95b0f3Sdrh     testHexToBin(zIn, zOut);
4207c95b0f3Sdrh     sqlite3_result_text16le(pCtx, zOut, n/2, sqlite3_free);
4217c95b0f3Sdrh   }
4227c95b0f3Sdrh }
42393a696f6Sdan #endif
4247c95b0f3Sdrh 
425984bfaa4Sdrh static int registerTestFunctions(sqlite3 *db){
426984bfaa4Sdrh   static const struct {
427984bfaa4Sdrh      char *zName;
428984bfaa4Sdrh      signed char nArg;
429984bfaa4Sdrh      unsigned char eTextRep; /* 1: UTF-16.  0: UTF-8 */
430984bfaa4Sdrh      void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
431984bfaa4Sdrh   } aFuncs[] = {
432984bfaa4Sdrh     { "randstr",               2, SQLITE_UTF8, randStr    },
433984bfaa4Sdrh     { "test_destructor",       1, SQLITE_UTF8, test_destructor},
4342a5fc4d6Sshane #ifndef SQLITE_OMIT_UTF16
435da84ca8dSdrh     { "test_destructor16",     1, SQLITE_UTF8, test_destructor16},
4367c95b0f3Sdrh     { "hex_to_utf16be",        1, SQLITE_UTF8, testHexToUtf16be},
4377c95b0f3Sdrh     { "hex_to_utf16le",        1, SQLITE_UTF8, testHexToUtf16le},
4382a5fc4d6Sshane #endif
4397c95b0f3Sdrh     { "hex_to_utf8",           1, SQLITE_UTF8, testHexToUtf8},
440984bfaa4Sdrh     { "test_destructor_count", 0, SQLITE_UTF8, test_destructor_count},
441984bfaa4Sdrh     { "test_auxdata",         -1, SQLITE_UTF8, test_auxdata},
442984bfaa4Sdrh     { "test_error",            1, SQLITE_UTF8, test_error},
44300e087b2Sdrh     { "test_error",            2, SQLITE_UTF8, test_error},
444a3460585Sdrh     { "test_eval",             1, SQLITE_UTF8, test_eval},
445191b54cbSdrh     { "test_isolation",        2, SQLITE_UTF8, test_isolation},
4461a4e3162Sdrh     { "test_counter",          1, SQLITE_UTF8, counterFunc},
447984bfaa4Sdrh   };
448984bfaa4Sdrh   int i;
449984bfaa4Sdrh 
450984bfaa4Sdrh   for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
451984bfaa4Sdrh     sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
452984bfaa4Sdrh         aFuncs[i].eTextRep, 0, aFuncs[i].xFunc, 0, 0);
453984bfaa4Sdrh   }
454238746a6Sdanielk1977 
455238746a6Sdanielk1977   sqlite3_create_function(db, "test_agg_errmsg16", 0, SQLITE_ANY, 0, 0,
456238746a6Sdanielk1977       test_agg_errmsg16_step, test_agg_errmsg16_final);
457238746a6Sdanielk1977 
458984bfaa4Sdrh   return SQLITE_OK;
459984bfaa4Sdrh }
460984bfaa4Sdrh 
461984bfaa4Sdrh /*
462984bfaa4Sdrh ** TCLCMD:  autoinstall_test_functions
463984bfaa4Sdrh **
464984bfaa4Sdrh ** Invoke this TCL command to use sqlite3_auto_extension() to cause
465984bfaa4Sdrh ** the standard set of test functions to be loaded into each new
466984bfaa4Sdrh ** database connection.
467984bfaa4Sdrh */
468984bfaa4Sdrh static int autoinstall_test_funcs(
469984bfaa4Sdrh   void * clientData,
470984bfaa4Sdrh   Tcl_Interp *interp,
471984bfaa4Sdrh   int objc,
472984bfaa4Sdrh   Tcl_Obj *CONST objv[]
473984bfaa4Sdrh ){
47465aa957aSdrh   extern int Md5_Register(sqlite3*);
475701bb3b4Sdrh   int rc = sqlite3_auto_extension((void*)registerTestFunctions);
47665aa957aSdrh   if( rc==SQLITE_OK ){
47765aa957aSdrh     rc = sqlite3_auto_extension((void*)Md5_Register);
47865aa957aSdrh   }
479701bb3b4Sdrh   Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
480984bfaa4Sdrh   return TCL_OK;
481984bfaa4Sdrh }
482984bfaa4Sdrh 
48324b58dd7Sdrh /*
48424b58dd7Sdrh ** A bogus step function and finalizer function.
48524b58dd7Sdrh */
48624b58dd7Sdrh static void tStep(sqlite3_context *a, int b, sqlite3_value **c){}
48724b58dd7Sdrh static void tFinal(sqlite3_context *a){}
48824b58dd7Sdrh 
48924b58dd7Sdrh 
49024b58dd7Sdrh /*
49124b58dd7Sdrh ** tclcmd:  abuse_create_function
49224b58dd7Sdrh **
49324b58dd7Sdrh ** Make various calls to sqlite3_create_function that do not have valid
49424b58dd7Sdrh ** parameters.  Verify that the error condition is detected and reported.
49524b58dd7Sdrh */
49624b58dd7Sdrh static int abuse_create_function(
49724b58dd7Sdrh   void * clientData,
49824b58dd7Sdrh   Tcl_Interp *interp,
49924b58dd7Sdrh   int objc,
50024b58dd7Sdrh   Tcl_Obj *CONST objv[]
50124b58dd7Sdrh ){
50224b58dd7Sdrh   extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
50324b58dd7Sdrh   sqlite3 *db;
50424b58dd7Sdrh   int rc;
50524b58dd7Sdrh   int mxArg;
50624b58dd7Sdrh 
50724b58dd7Sdrh   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
50824b58dd7Sdrh 
50924b58dd7Sdrh   rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, tStep,tStep,tFinal);
510dff6c173Sdrh   if( rc!=SQLITE_MISUSE ) goto abuse_err;
51124b58dd7Sdrh 
51224b58dd7Sdrh   rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, tStep, tStep, 0);
513dff6c173Sdrh   if( rc!=SQLITE_MISUSE ) goto abuse_err;
51424b58dd7Sdrh 
51524b58dd7Sdrh   rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, tStep, 0, tFinal);
516dff6c173Sdrh   if( rc!=SQLITE_MISUSE) goto abuse_err;
51724b58dd7Sdrh 
51824b58dd7Sdrh   rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, 0, 0, tFinal);
519dff6c173Sdrh   if( rc!=SQLITE_MISUSE ) goto abuse_err;
52024b58dd7Sdrh 
52124b58dd7Sdrh   rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, 0, tStep, 0);
522dff6c173Sdrh   if( rc!=SQLITE_MISUSE ) goto abuse_err;
52324b58dd7Sdrh 
52424b58dd7Sdrh   rc = sqlite3_create_function(db, "tx", -2, SQLITE_UTF8, 0, tStep, 0, 0);
525dff6c173Sdrh   if( rc!=SQLITE_MISUSE ) goto abuse_err;
52624b58dd7Sdrh 
52724b58dd7Sdrh   rc = sqlite3_create_function(db, "tx", 128, SQLITE_UTF8, 0, tStep, 0, 0);
528dff6c173Sdrh   if( rc!=SQLITE_MISUSE ) goto abuse_err;
52924b58dd7Sdrh 
53024b58dd7Sdrh   rc = sqlite3_create_function(db, "funcxx"
53124b58dd7Sdrh        "_123456789_123456789_123456789_123456789_123456789"
53224b58dd7Sdrh        "_123456789_123456789_123456789_123456789_123456789"
53324b58dd7Sdrh        "_123456789_123456789_123456789_123456789_123456789"
53424b58dd7Sdrh        "_123456789_123456789_123456789_123456789_123456789"
53524b58dd7Sdrh        "_123456789_123456789_123456789_123456789_123456789",
53624b58dd7Sdrh        1, SQLITE_UTF8, 0, tStep, 0, 0);
537dff6c173Sdrh   if( rc!=SQLITE_MISUSE ) goto abuse_err;
53824b58dd7Sdrh 
53924b58dd7Sdrh   /* This last function registration should actually work.  Generate
54024b58dd7Sdrh   ** a no-op function (that always returns NULL) and which has the
54124b58dd7Sdrh   ** maximum-length function name and the maximum number of parameters.
54224b58dd7Sdrh   */
54324b58dd7Sdrh   sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, 10000);
54424b58dd7Sdrh   mxArg = sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, -1);
54524b58dd7Sdrh   rc = sqlite3_create_function(db, "nullx"
54624b58dd7Sdrh        "_123456789_123456789_123456789_123456789_123456789"
54724b58dd7Sdrh        "_123456789_123456789_123456789_123456789_123456789"
54824b58dd7Sdrh        "_123456789_123456789_123456789_123456789_123456789"
54924b58dd7Sdrh        "_123456789_123456789_123456789_123456789_123456789"
55024b58dd7Sdrh        "_123456789_123456789_123456789_123456789_123456789",
55124b58dd7Sdrh        mxArg, SQLITE_UTF8, 0, tStep, 0, 0);
55224b58dd7Sdrh   if( rc!=SQLITE_OK ) goto abuse_err;
55324b58dd7Sdrh 
55424b58dd7Sdrh   return TCL_OK;
55524b58dd7Sdrh 
55624b58dd7Sdrh abuse_err:
55724b58dd7Sdrh   Tcl_AppendResult(interp, "sqlite3_create_function abused test failed",
55824b58dd7Sdrh                    (char*)0);
55924b58dd7Sdrh   return TCL_ERROR;
56024b58dd7Sdrh }
56124b58dd7Sdrh 
562984bfaa4Sdrh /*
563984bfaa4Sdrh ** Register commands with the TCL interpreter.
564984bfaa4Sdrh */
565984bfaa4Sdrh int Sqlitetest_func_Init(Tcl_Interp *interp){
566984bfaa4Sdrh   static struct {
567984bfaa4Sdrh      char *zName;
568984bfaa4Sdrh      Tcl_ObjCmdProc *xProc;
569984bfaa4Sdrh   } aObjCmd[] = {
570984bfaa4Sdrh      { "autoinstall_test_functions",    autoinstall_test_funcs },
57124b58dd7Sdrh      { "abuse_create_function",         abuse_create_function  },
572984bfaa4Sdrh   };
573984bfaa4Sdrh   int i;
57465aa957aSdrh   extern int Md5_Register(sqlite3*);
57565aa957aSdrh 
576984bfaa4Sdrh   for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
577984bfaa4Sdrh     Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
578984bfaa4Sdrh   }
57900f0faf3Sdanielk1977   sqlite3_initialize();
580984bfaa4Sdrh   sqlite3_auto_extension((void*)registerTestFunctions);
58165aa957aSdrh   sqlite3_auto_extension((void*)Md5_Register);
582984bfaa4Sdrh   return TCL_OK;
583984bfaa4Sdrh }
584