------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Enhanced\sdocumentation\sand\sminor\scode\stweaks\sin\spreparation\sfor\shardening\nthe\ssqlite3_initialize/shutdown\sinterfaces\sagainst\sinitialization\sfailures.
-D 2009-08-17T13:42:30
+C Add\stests\sto\scheck\sthat\ssqlite\srecovers\sfrom\san\serror\sin\ssqlite3_initialize()\scorrectly.
+D 2009-08-17T15:16:19
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 0f7761c5d1c62ae7a841e3393ffaff1fa0f5c00a
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F ext/rtree/viewrtree.tcl 09526398dae87a5a87c5aac2b3854dbaf8376869
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
-F main.mk 6272ba6c273b6390602b276dd2b1e4fe71d1049a
+F main.mk 3ae48161d5a76def45cd8fa253b28295f239dd69
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
F src/expr.c d069ba1e060f296ea4f18fb85198fafefd00b22f
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
F src/func.c e536218d193b8d326aab91120bc4c6f28aa2b606
-F src/global.c 263dea92c89956eef9335fe2cf6af8e3fa34646b
+F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32
F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7
F src/hash.h 35b216c13343d0b4f87d9f21969ac55ad72174e1
F src/hwtime.h 4a1d45f4cae1f402ea19686acf24acf4f0cb53cb
F src/legacy.c 303b4ffcf1ae652fcf5ef635846c563c254564f6
F src/lempar.c 0c4d1ab0a5ef2b0381eb81a732c54f68f27a574d
F src/loadext.c 0e88a335665db0b2fb4cece3e49dcb65d832635a
-F src/main.c 6873986c416ce78e8102b5189aef1179053be4e9
+F src/main.c cb283c9e98d50cb14b01d6b736c4336f7bf07189
F src/malloc.c ae9fef00398ead775630cad97e228d527178eb3a
F src/mem0.c f2f84062d1f35814d6535c9f9e33de3bfb3b132c
F src/mem1.c e6d5c23941288df8191b8a98c28e3f57771e2270
F src/os.h fa3f4aa0119ff721a2da4b47ffd74406ac864c05
F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
-F src/os_unix.c cdb2a08b9ce4aa13b3f7b91d4dd60fb48be9f56a
-F src/os_win.c 6de69d8f51d4bf35484e9be1588089a61569491f
+F src/os_unix.c aea2a5c1c07c47767b0961b670dc647aa4aefc4e
+F src/os_win.c a3e93d1b44a818ce9422e2e588984df1cb7e4819
F src/pager.c a47be286477ed6c7b9a342dd53d4e4043f29d8c2
F src/pager.h 11852d044c86cf5a9d6e34171fb0c4fcf1f6265f
F src/parse.y 6c42631e72a3d14cde2bee85e79409066066d3df
F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb
F src/sqlite.h.in b309f8f5ecc76fc2d56a32d6563b3636901befb1
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
-F src/sqliteInt.h 6a90791138ba3447572d184d0798c24f3cbbec98
+F src/sqliteInt.h d675e20da30db2c28e7166deb1fc758fb5b29a9a
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
-F src/tclsqlite.c e18e5013dc6bca9f25e6022fbe17ba3ccb821f95
+F src/tclsqlite.c 5eea5025c370d3a91ce0415f9d46f96fdc7aef44
F src/test1.c 0e882812c94cf35fce30fc25fbf952a33a86d70b
F src/test2.c 0de743ec8890ca4f09e0bce5d6d5a681f5957fec
F src/test3.c 2445c2beb5e7a0c91fd8136dc1339ec369a24898
F src/test_devsym.c 9f4bc2551e267ce7aeda195f3897d0f30c5228f4
F src/test_func.c 26ac62d8ed7a9f45a1e05baffb1c1e55fe2a06f2
F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f
+F src/test_init.c ff7c0e055fb786f5b048df83b6dfb1624851a88b
F src/test_journal.c dab49b7c47b53242f039c9563b18cafb67ebfe03
F src/test_loadext.c 97dc8800e46a46ed002c2968572656f37e9c0dd9
F src/test_malloc.c d054506b095d711e4e5575558dd576a2cbf035a2
F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
F test/index3.test 727d55dceb9a4ec36675057bb5becfc265e28ca6
F test/indexedby.test 946ca2628a521f4ced0520421a0788345abaf3dc
+F test/init.test 5768d2cfeb25df627d42de675ab6201a65c167fe
F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
-P 78dfe8321db9debfcd4a7f3daf4223d0cbf23ab9
-R 59b834c230f554631ea111aff633ae3d
-U drh
-Z 14a85d4458d8211ec1ee47b0a57f04f9
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFKiV5JoxKgR168RlERAhxLAJ9VpGZymsNQGLlIzDsn3KQPM4CSYgCfR70O
-KCNsn02bCPSvHz/OQJ5kVZc=
-=CGmi
------END PGP SIGNATURE-----
+P 98c49e6135ae6268a80de88f8b0284f88ef32e1d
+R 403bbd0c163020937b591c0dbd3d7490
+U dan
+Z d3982d3f3fe40cd70ed5dd9628e2f879
--- /dev/null
+/*
+** 2009 August 17
+**
+** 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.
+**
+*************************************************************************
+**
+** The code in this file is used for testing SQLite. It is not part of
+** the source code used in production systems.
+**
+** Specifically, this file tests the effect of errors while initializing
+** the various pluggable sub-systems from within sqlite3_initialize().
+** If an error occurs in sqlite3_initialize() the following should be
+** true:
+**
+** 1) An error code is returned to the user, and
+** 2) A subsequent call to sqlite3_shutdown() calls the shutdown method
+** of those subsystems that were initialized, and
+** 3) A subsequent call to sqlite3_initialize() attempts to initialize
+** the remaining, uninitialized, subsystems.
+*/
+
+#include "sqliteInt.h"
+#include <string.h>
+#include <tcl.h>
+
+static struct Wrapped {
+ sqlite3_pcache_methods pcache;
+ sqlite3_mem_methods mem;
+ sqlite3_mutex_methods mutex;
+
+ int mem_init; /* True if mem subsystem is initalized */
+ int mem_fail; /* True to fail mem subsystem inialization */
+ int mutex_init; /* True if mutex subsystem is initalized */
+ int mutex_fail; /* True to fail mutex subsystem inialization */
+ int pcache_init; /* True if pcache subsystem is initalized */
+ int pcache_fail; /* True to fail pcache subsystem inialization */
+ int osinit_fail; /* True to fail OS subsystem inialization */
+} wrapped;
+
+static int wrMemInit(void *pAppData){
+ int rc;
+ if( wrapped.mem_fail ){
+ rc = SQLITE_ERROR;
+ }else{
+ rc = wrapped.mem.xInit(wrapped.mem.pAppData);
+ }
+ if( rc==SQLITE_OK ){
+ wrapped.mem_init = 1;
+ }
+ return rc;
+}
+static void wrMemShutdown(void *pAppData){
+ wrapped.mem.xShutdown(wrapped.mem.pAppData);
+ wrapped.mem_init = 0;
+}
+static void *wrMemMalloc(int n) {return wrapped.mem.xMalloc(n);}
+static void wrMemFree(void *p) {wrapped.mem.xFree(p);}
+static void *wrMemRealloc(void *p, int n) {return wrapped.mem.xRealloc(p, n);}
+static int wrMemSize(void *p) {return wrapped.mem.xSize(p);}
+static int wrMemRoundup(int n) {return wrapped.mem.xRoundup(n);}
+
+
+static int wrMutexInit(void){
+ int rc;
+ if( wrapped.mutex_fail ){
+ rc = SQLITE_ERROR;
+ }else{
+ rc = wrapped.mutex.xMutexInit();
+ }
+ if( rc==SQLITE_OK ){
+ wrapped.mutex_init = 1;
+ }
+ return rc;
+}
+static int wrMutexEnd(void){
+ wrapped.mutex.xMutexEnd();
+ wrapped.mutex_init = 0;
+ return SQLITE_OK;
+}
+static sqlite3_mutex *wrMutexAlloc(int e){
+ return wrapped.mutex.xMutexAlloc(e);
+}
+static void wrMutexFree(sqlite3_mutex *p){
+ wrapped.mutex.xMutexFree(p);
+}
+static void wrMutexEnter(sqlite3_mutex *p){
+ wrapped.mutex.xMutexEnter(p);
+}
+static int wrMutexTry(sqlite3_mutex *p){
+ return wrapped.mutex.xMutexTry(p);
+}
+static void wrMutexLeave(sqlite3_mutex *p){
+ wrapped.mutex.xMutexLeave(p);
+}
+static int wrMutexHeld(sqlite3_mutex *p){
+ return wrapped.mutex.xMutexHeld(p);
+}
+static int wrMutexNotheld(sqlite3_mutex *p){
+ return wrapped.mutex.xMutexNotheld(p);
+}
+
+
+
+static int wrPCacheInit(void *pArg){
+ int rc;
+ if( wrapped.pcache_fail ){
+ rc = SQLITE_ERROR;
+ }else{
+ rc = wrapped.pcache.xInit(wrapped.pcache.pArg);
+ }
+ if( rc==SQLITE_OK ){
+ wrapped.pcache_init = 1;
+ }
+ return rc;
+}
+static void wrPCacheShutdown(void *pArg){
+ wrapped.pcache.xShutdown(wrapped.pcache.pArg);
+ wrapped.pcache_init = 0;
+}
+
+static sqlite3_pcache *wrPCacheCreate(int a, int b){
+ return wrapped.pcache.xCreate(a, b);
+}
+static void wrPCacheCachesize(sqlite3_pcache *p, int n){
+ wrapped.pcache.xCachesize(p, n);
+}
+static int wrPCachePagecount(sqlite3_pcache *p){
+ return wrapped.pcache.xPagecount(p);
+}
+static void *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
+ return wrapped.pcache.xFetch(p, a, b);
+}
+static void wrPCacheUnpin(sqlite3_pcache *p, void *a, int b){
+ wrapped.pcache.xUnpin(p, a, b);
+}
+static void wrPCacheRekey(sqlite3_pcache *p, void *a, unsigned b, unsigned c){
+ wrapped.pcache.xRekey(p, a, b, c);
+}
+static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){
+ wrapped.pcache.xTruncate(p, a);
+}
+static void wrPCacheDestroy(sqlite3_pcache *p){
+ wrapped.pcache.xDestroy(p);
+}
+
+static void installInitWrappers(void){
+ sqlite3_mutex_methods mutexmethods = {
+ wrMutexInit, wrMutexEnd, wrMutexAlloc,
+ wrMutexFree, wrMutexEnter, wrMutexTry,
+ wrMutexLeave, wrMutexHeld, wrMutexNotheld
+ };
+ sqlite3_pcache_methods pcachemethods = {
+ 0,
+ wrPCacheInit, wrPCacheShutdown, wrPCacheCreate,
+ wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
+ wrPCacheUnpin, wrPCacheRekey, wrPCacheTruncate,
+ wrPCacheDestroy
+ };
+ sqlite3_mem_methods memmethods = {
+ wrMemMalloc, wrMemFree, wrMemRealloc,
+ wrMemSize, wrMemRoundup, wrMemInit,
+ wrMemShutdown,
+ 0
+ };
+
+ memset(&wrapped, 0, sizeof(wrapped));
+
+ sqlite3_shutdown();
+ sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex);
+ sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem);
+ sqlite3_config(SQLITE_CONFIG_GETPCACHE, &wrapped.pcache);
+ sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods);
+ sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods);
+ sqlite3_config(SQLITE_CONFIG_PCACHE, &pcachemethods);
+}
+
+static int init_wrapper_install(
+ ClientData clientData, /* Unused */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ int i;
+ installInitWrappers();
+ for(i=1; i<objc; i++){
+ char *z = Tcl_GetString(objv[i]);
+ if( strcmp(z, "mem")==0 ){
+ wrapped.mem_fail = 1;
+ }else if( strcmp(z, "mutex")==0 ){
+ wrapped.mutex_fail = 1;
+ }else if( strcmp(z, "pcache")==0 ){
+ wrapped.pcache_fail = 1;
+ }else if( strcmp(z, "os")==0 ){
+ wrapped.osinit_fail = 1;
+ }else{
+ Tcl_AppendResult(interp, "Unknown argument: \"", z, "\"");
+ return TCL_ERROR;
+ }
+ }
+ return TCL_OK;
+}
+
+static int init_wrapper_uninstall(
+ ClientData clientData, /* Unused */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ if( objc!=1 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "");
+ return TCL_ERROR;
+ }
+
+ memset(&wrapped, 0, sizeof(&wrapped));
+ sqlite3_shutdown();
+ sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
+ sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
+ sqlite3_config(SQLITE_CONFIG_PCACHE, &wrapped.pcache);
+ return TCL_OK;
+}
+
+static int init_wrapper_clear(
+ ClientData clientData, /* Unused */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ if( objc!=1 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "");
+ return TCL_ERROR;
+ }
+
+ wrapped.mem_fail = 0;
+ wrapped.mutex_fail = 0;
+ wrapped.pcache_fail = 0;
+ wrapped.osinit_fail = 0;
+ return TCL_OK;
+}
+
+static int init_wrapper_query(
+ ClientData clientData, /* Unused */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ Tcl_Obj *pRet;
+
+ if( objc!=1 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "");
+ return TCL_ERROR;
+ }
+
+ pRet = Tcl_NewObj();
+ if( wrapped.mutex_init ){
+ Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mutex", -1));
+ }
+ if( wrapped.mem_init ){
+ Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mem", -1));
+ }
+ if( wrapped.pcache_init ){
+ Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("pcache", -1));
+ }
+ if( sqlite3GlobalConfig.isInit ){
+ Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("os", -1));
+ }
+
+ Tcl_SetObjResult(interp, pRet);
+ return TCL_OK;
+}
+
+int sqlite3TestFailOsInit(void){
+ return (wrapped.mem.xMalloc && wrapped.osinit_fail);
+}
+
+int Sqlitetest_init_Init(Tcl_Interp *interp){
+ static struct {
+ char *zName;
+ Tcl_ObjCmdProc *xProc;
+ } aObjCmd[] = {
+ {"init_wrapper_install", init_wrapper_install},
+ {"init_wrapper_query", init_wrapper_query },
+ {"init_wrapper_uninstall", init_wrapper_uninstall},
+ {"init_wrapper_clear", init_wrapper_clear}
+ };
+ int i;
+
+ for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
+ Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
+ }
+
+ return TCL_OK;
+}
+