Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | The ability to load extensions is turned off by default. It must be enabled by calling sqlite3_enable_load_extension() before it will work. This prevents security problems in legacy applications. Ticket #1863. (CVS 3311) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4692319ccf28b0ebe64d5c5d189f4440 |
User & Date: | drh 2006-06-27 15:16:15 |
Context
2006-06-27
| ||
16:34 | Prevent databases from being DETACHed while they are in use. Fix for #1873. (CVS 3312) (check-in: 70a48b25 user: danielk1977 tags: trunk) | |
15:16 | The ability to load extensions is turned off by default. It must be enabled by calling sqlite3_enable_load_extension() before it will work. This prevents security problems in legacy applications. Ticket #1863. (CVS 3311) (check-in: 4692319c user: drh tags: trunk) | |
14:37 | Changes to build successfully with -DSQLITE_OMIT_LOAD_EXTENSION=1 (CVS 3310) (check-in: 783369e8 user: drh tags: trunk) | |
Changes
Changes to src/loadext.c.
︙ | ︙ | |||
256 257 258 259 260 261 262 263 264 265 266 267 268 269 | char **pzErrMsg /* Put error message here if not 0 */ ){ #ifdef SQLITE_LIBRARY_TYPE SQLITE_LIBRARY_TYPE handle; int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); char *zErrmsg = 0; SQLITE_LIBRARY_TYPE *aHandle; if( zProc==0 ){ zProc = "sqlite3_extension_init"; } handle = SQLITE_OPEN_LIBRARY(zFile); if( handle==0 ){ | > > > > > > > > > > > > > | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | char **pzErrMsg /* Put error message here if not 0 */ ){ #ifdef SQLITE_LIBRARY_TYPE SQLITE_LIBRARY_TYPE handle; int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); char *zErrmsg = 0; SQLITE_LIBRARY_TYPE *aHandle; /* Ticket #1863. To avoid a creating security problems for older ** applications that relink against newer versions of SQLite, the ** ability to run load_extension is turned off by default. One ** must call sqlite3_enable_load_extension() to turn on extension ** loading. Otherwise you get the following error. */ if( (db->flags & SQLITE_LoadExtension)==0 ){ if( pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("not authorized"); } return SQLITE_ERROR; } if( zProc==0 ){ zProc = "sqlite3_extension_init"; } handle = SQLITE_OPEN_LIBRARY(zFile); if( handle==0 ){ |
︙ | ︙ | |||
321 322 323 324 325 326 327 328 329 | int i; for(i=0; i<db->nExtension; i++){ SQLITE_CLOSE_LIBRARY(((SQLITE_LIBRARY_TYPE*)db->aExtension)[i]); } sqliteFree(db->aExtension); #endif } #endif /* SQLITE_OMIT_LOAD_EXTENSION */ | > > > > > > > > > > > > > | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | int i; for(i=0; i<db->nExtension; i++){ SQLITE_CLOSE_LIBRARY(((SQLITE_LIBRARY_TYPE*)db->aExtension)[i]); } sqliteFree(db->aExtension); #endif } /* ** Enable or disable extension loading. Extension loading is disabled by ** default so as not to open security holes in older applications. */ int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ if( onoff ){ db->flags |= SQLITE_LoadExtension; }else{ db->flags &= ~SQLITE_LoadExtension; } return SQLITE_OK; } #endif /* SQLITE_OMIT_LOAD_EXTENSION */ |
Changes to src/shell.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** ** $Id: shell.c,v 1.143 2006/06/27 15:16:15 drh Exp $ */ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <assert.h> #include "sqlite3.h" #include <ctype.h> |
︙ | ︙ | |||
803 804 805 806 807 808 809 810 811 812 813 814 815 816 | sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0, shellstaticFunc, 0, 0); if( SQLITE_OK!=sqlite3_errcode(db) ){ fprintf(stderr,"Unable to open database \"%s\": %s\n", p->zDbFilename, sqlite3_errmsg(db)); exit(1); } } } /* ** Do C-language style dequoting. ** ** \t -> tab | > > > | 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 | sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0, shellstaticFunc, 0, 0); if( SQLITE_OK!=sqlite3_errcode(db) ){ fprintf(stderr,"Unable to open database \"%s\": %s\n", p->zDbFilename, sqlite3_errmsg(db)); exit(1); } #ifndef SQLITE_OMIT_LOAD_EXTENSION sqlite3_enable_load_extension(p->db, 1); #endif } } /* ** Do C-language style dequoting. ** ** \t -> tab |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.185 2006/06/27 15:16:15 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
1481 1482 1483 1484 1485 1486 1487 | ); /* ****** EXPERIMENTAL - subject to change without notice ************** ** ** Attempt to load an SQLite extension library contained in the file ** zFile. The entry point is zProc. zProc may be 0 in which case the | | | | < < < < < < < < < < < < < < < > > > > > > > > > > > > | 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 | ); /* ****** EXPERIMENTAL - subject to change without notice ************** ** ** Attempt to load an SQLite extension library contained in the file ** zFile. The entry point is zProc. zProc may be 0 in which case the ** name of the entry point defaults to "sqlite3_extension_init". ** ** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. ** ** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with ** error message text. The calling function should free this memory ** by calling sqlite3_free(). ** ** Extension loading must be enabled using sqlite3_enable_load_extension() ** prior to calling this API or an error will be returned. ** ****** EXPERIMENTAL - subject to change without notice ************** */ int sqlite3_load_extension( sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Derived from zFile if 0 */ char **pzErrMsg /* Put error message here if not 0 */ ); /* ** So as not to open security holes in older applications that are ** unprepared to deal with extension load, and as a means of disabling ** extension loading while executing user-entered SQL, the following ** API is provided to turn the extension loading mechanism on and ** off. It is off by default. See ticket #1863. ** ** Call this routine with onoff==1 to turn extension loading on ** and call it with onoff==0 to turn it back off again. */ int sqlite3_enable_load_extension(sqlite3 *db, int onoff); /* ****** EXPERIMENTAL - subject to change without notice ************** ** ** The interface to the virtual-table mechanism is currently considered ** to be experimental. The interface might change in incompatible ways. ** If this is a problem for you, do not use the interface at this time. ** |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.517 2006/06/27 15:16:15 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Extra interface definitions for those who need them */ |
︙ | ︙ | |||
532 533 534 535 536 537 538 | /* result set is empty */ #define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */ #define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */ #define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */ #define SQLITE_NoReadlock 0x00001000 /* Readlocks are omitted when ** accessing read-only databases */ #define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */ | | > | 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | /* result set is empty */ #define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */ #define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */ #define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */ #define SQLITE_NoReadlock 0x00001000 /* Readlocks are omitted when ** accessing read-only databases */ #define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */ #define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */ #define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */ #define SQLITE_FullFSync 0x00010000 /* Use full fsync on the backend */ #define SQLITE_LoadExtension 0x00020000 /* Enable load_extension */ /* ** Possible values for the sqlite.magic field. ** The numbers are obtained at random and have no special meaning, other ** than being distinct from one another. */ #define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */ |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.215 2006/06/27 15:16:16 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 | Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(primarykey)); Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(autoincrement)); Tcl_SetObjResult(interp, pRet); return TCL_OK; } #endif /* ** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC? */ static int test_load_extension( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ | > | 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 | Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(primarykey)); Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(autoincrement)); Tcl_SetObjResult(interp, pRet); return TCL_OK; } #endif /* ** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC? */ static int test_load_extension( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
︙ | ︙ | |||
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 | db = ((struct SqliteDb*)cmdInfo.objClientData)->db; assert(db); /* Call the underlying C function. If an error occurs, set rc to ** TCL_ERROR and load any error string into the interpreter. If no ** error occurs, set rc to TCL_OK. */ rc = sqlite3_load_extension(db, zFile, zProc, &zErr); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, zErr ? zErr : "", TCL_VOLATILE); rc = TCL_ERROR; }else{ rc = TCL_OK; } sqlite3_free(zErr); return rc; } /* ** Usage: sqlite_abort ** ** Shutdown the process immediately. This is not a clean shutdown. ** This command is used to test the recoverability of a database in ** the event of a program crash. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 | db = ((struct SqliteDb*)cmdInfo.objClientData)->db; assert(db); /* Call the underlying C function. If an error occurs, set rc to ** TCL_ERROR and load any error string into the interpreter. If no ** error occurs, set rc to TCL_OK. */ #ifdef SQLITE_OMIT_LOAD_EXTENSION rc = SQLITE_ERROR; zErr = sqlite3_mprintf("this build omits sqlite3_load_extension()"); #else rc = sqlite3_load_extension(db, zFile, zProc, &zErr); #endif if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, zErr ? zErr : "", TCL_VOLATILE); rc = TCL_ERROR; }else{ rc = TCL_OK; } sqlite3_free(zErr); return rc; } /* ** Usage: sqlite3_enable_load_extension DB-HANDLE ONOFF */ static int test_enable_load( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ Tcl_CmdInfo cmdInfo; sqlite3 *db; char *zDb; int onoff; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE ONOFF"); return TCL_ERROR; } zDb = Tcl_GetString(objv[1]); /* Extract the C database handle from the Tcl command name */ if( !Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){ Tcl_AppendResult(interp, "command not found: ", zDb, (char*)0); return TCL_ERROR; } db = ((struct SqliteDb*)cmdInfo.objClientData)->db; assert(db); /* Get the onoff parameter */ if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){ return TCL_ERROR; } #ifdef SQLITE_OMIT_LOAD_EXTENSION Tcl_AppendResult(interp, "this build omits sqlite3_load_extension()"); return TCL_ERROR; #else sqlite3_enable_load_extension(db, onoff); return TCL_OK; #endif } /* ** Usage: sqlite_abort ** ** Shutdown the process immediately. This is not a clean shutdown. ** This command is used to test the recoverability of a database in ** the event of a program crash. |
︙ | ︙ | |||
3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 | { "sqlite3_release_memory", test_release_memory, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, { "sqlite3_clear_tsd_memdebug", test_clear_tsd_memdebug, 0}, { "sqlite3_tsd_release", test_tsd_release, 0}, { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, /* sqlite3_column_*() API */ { "sqlite3_column_count", test_column_count ,0 }, { "sqlite3_data_count", test_data_count ,0 }, { "sqlite3_column_type", test_column_type ,0 }, { "sqlite3_column_blob", test_column_blob ,0 }, { "sqlite3_column_double", test_column_double ,0 }, { "sqlite3_column_int64", test_column_int64 ,0 }, | > > > | 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 | { "sqlite3_release_memory", test_release_memory, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, { "sqlite3_clear_tsd_memdebug", test_clear_tsd_memdebug, 0}, { "sqlite3_tsd_release", test_tsd_release, 0}, { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, { "sqlite3_load_extension", test_load_extension, 0}, { "sqlite3_enable_load_extension", test_enable_load, 0}, /* sqlite3_column_*() API */ { "sqlite3_column_count", test_column_count ,0 }, { "sqlite3_data_count", test_data_count ,0 }, { "sqlite3_column_type", test_column_type ,0 }, { "sqlite3_column_blob", test_column_blob ,0 }, { "sqlite3_column_double", test_column_double ,0 }, { "sqlite3_column_int64", test_column_int64 ,0 }, |
︙ | ︙ | |||
3748 3749 3750 3751 3752 3753 3754 | #ifndef SQLITE_OMIT_SHARED_CACHE { "sqlite3_enable_shared_cache", test_enable_shared, 0 }, #endif { "sqlite3_libversion_number", test_libversion_number, 0 }, #ifdef SQLITE_ENABLE_COLUMN_METADATA { "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, #endif | < < < | 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 | #ifndef SQLITE_OMIT_SHARED_CACHE { "sqlite3_enable_shared_cache", test_enable_shared, 0 }, #endif { "sqlite3_libversion_number", test_libversion_number, 0 }, #ifdef SQLITE_ENABLE_COLUMN_METADATA { "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, #endif }; static int bitmask_size = sizeof(Bitmask)*8; int i; extern int sqlite3_os_trace; extern int sqlite3_where_trace; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; |
︙ | ︙ |
Changes to test/loadext.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2006 July 14 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is in-memory database backend. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2006 July 14 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is in-memory database backend. # # $Id: loadext.test,v 1.5 2006/06/27 15:16:16 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # The name of the test extension varies by operating system. # if {$::tcl_platform(platform) eq "windows"} { |
︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | # do_test loadext-1.1 { catchsql { SELECT half(1.0); } } {1 {no such function: half}} do_test loadext-1.2 { sqlite3_load_extension db $testextension testloadext_init catchsql { SELECT half(1.0); } } {0 0.5} # Test that a second database connection (db2) can load the extension also. # do_test loadext-1.3 { sqlite3 db2 test.db catchsql { SELECT half(1.0); } db2 } {1 {no such function: half}} do_test loadext-1.4 { sqlite3_load_extension db2 $testextension testloadext_init catchsql { | > > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | # do_test loadext-1.1 { catchsql { SELECT half(1.0); } } {1 {no such function: half}} do_test loadext-1.2 { sqlite3_enable_load_extension db 1 sqlite3_load_extension db $testextension testloadext_init catchsql { SELECT half(1.0); } } {0 0.5} # Test that a second database connection (db2) can load the extension also. # do_test loadext-1.3 { sqlite3 db2 test.db sqlite3_enable_load_extension db2 1 catchsql { SELECT half(1.0); } db2 } {1 {no such function: half}} do_test loadext-1.4 { sqlite3_load_extension db2 $testextension testloadext_init catchsql { |
︙ | ︙ | |||
79 80 81 82 83 84 85 86 87 88 89 90 91 92 | catchsql { SELECT half(1.0); } db2 } {0 0.5} db2 close sqlite3 db test.db # Try to load an extension for which the file does not exist. # do_test loadext-2.1 { set rc [catch { sqlite3_load_extension db "${testextension}xx" } msg] | > | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | catchsql { SELECT half(1.0); } db2 } {0 0.5} db2 close sqlite3 db test.db sqlite3_enable_load_extension db 1 # Try to load an extension for which the file does not exist. # do_test loadext-2.1 { set rc [catch { sqlite3_load_extension db "${testextension}xx" } msg] |
︙ | ︙ | |||
132 133 134 135 136 137 138 139 140 141 142 143 144 145 | ############################################################################ # Tests for the load_extension() SQL function # db close sqlite3 db test.db do_test loadext-3.1 { catchsql { SELECT half(5); } } {1 {no such function: half}} do_test loadext-3.2 { catchsql { | > | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | ############################################################################ # Tests for the load_extension() SQL function # db close sqlite3 db test.db sqlite3_enable_load_extension db 1 do_test loadext-3.1 { catchsql { SELECT half(5); } } {1 {no such function: half}} do_test loadext-3.2 { catchsql { |
︙ | ︙ | |||
153 154 155 156 157 158 159 160 161 | } } {0 {{}}} do_test loadext-3.4 { catchsql { SELECT half(5); } } {0 2.5} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | } } {0 {{}}} do_test loadext-3.4 { catchsql { SELECT half(5); } } {0 2.5} # Ticket #1863 # Make sure the extension loading mechanism will not work unless it # is explicitly enabled. # db close sqlite3 db test.db do_test loadext-4.1 { catchsql { SELECT load_extension($::testextension,'testloadext_init') } } {1 {not authorized}} do_test loadext-4.2 { sqlite3_enable_load_extension db 1 catchsql { SELECT load_extension($::testextension,'testloadext_init') } } {0 {{}}} do_test loadext-4.3 { sqlite3_enable_load_extension db 0 catchsql { SELECT load_extension($::testextension,'testloadext_init') } } {1 {not authorized}} finish_test |