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