From 4ffc078e9aa7ba4cdd669749ef6fd455140bf62e Mon Sep 17 00:00:00 2001 From: utelle Date: Wed, 27 Apr 2022 23:18:15 +0200 Subject: [PATCH] Prepare release of wxSQLite3 4.8.0 - Update to SQLite3 Multiple Ciphers 1.4.2 (based on SQLite 3.38.3) --- configure.ac | 2 +- docs/Doxyfile | 2 +- include/wx/wxsqlite3_version.h | 6 +- include/wx/wxsqlite3def.h | 6 + readme.md | 2 + src/sqlite3mc_amalgamation.c | 291 ++++++++++++++++++++++----------- src/sqlite3mc_amalgamation.h | 12 +- 7 files changed, 213 insertions(+), 108 deletions(-) diff --git a/configure.ac b/configure.ac index ed0223ef..e2b7d51a 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ dnl Copyright (C) 2017-2021 Ulrich Telle , Vadim Zeitlin dnl dnl This file is covered by the same licence as the entire wxSQLite3 package. -AC_INIT([wxsqlite3], [4.7.9], [ulrich@telle-online.de]) +AC_INIT([wxsqlite3], [4.8.0], [ulrich@telle-online.de]) dnl This is the version tested with, might work with earlier ones. AC_PREREQ([2.69]) diff --git a/docs/Doxyfile b/docs/Doxyfile index b3062766..2f65ce4a 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = wxSQLite3 # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 4.7.9 +PROJECT_NUMBER = 4.8.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/include/wx/wxsqlite3_version.h b/include/wx/wxsqlite3_version.h index fc4633f5..26dc64bc 100644 --- a/include/wx/wxsqlite3_version.h +++ b/include/wx/wxsqlite3_version.h @@ -13,9 +13,9 @@ #define WXSQLITE3_VERSION_H_ #define WXSQLITE3_MAJOR_VERSION 4 -#define WXSQLITE3_MINOR_VERSION 7 -#define WXSQLITE3_RELEASE_NUMBER 9 +#define WXSQLITE3_MINOR_VERSION 8 +#define WXSQLITE3_RELEASE_NUMBER 0 #define WXSQLITE3_SUBRELEASE_NUMBER 0 -#define WXSQLITE3_VERSION_STRING "wxSQLite3 4.7.9" +#define WXSQLITE3_VERSION_STRING "wxSQLite3 4.8.0" #endif // WXSQLITE3_VERSION_H_ diff --git a/include/wx/wxsqlite3def.h b/include/wx/wxsqlite3def.h index 3ba70e0b..b5453dfe 100644 --- a/include/wx/wxsqlite3def.h +++ b/include/wx/wxsqlite3def.h @@ -46,6 +46,12 @@
+
4.8.0 - April 2022
+
+Upgrade to SQLite3 Multiple Ciphers version 1.4.2 (SQLite version 3.38.3)
+ +
+
4.7.9 - April 2022
Upgrade to SQLite3 Multiple Ciphers version 1.3.10 (SQLite version 3.38.2)
diff --git a/readme.md b/readme.md index bf524c9d..e2ee8323 100644 --- a/readme.md +++ b/readme.md @@ -48,6 +48,8 @@ Since August 2020 a new implementation of an encryption extension, capable of su ## Version history +* 4.8.0 - *April 2022* + - Upgrade to SQLite3 Multiple Ciphers version 1.4.2 (SQLite version 3.38.3) * 4.7.9 - *April 2022* - Upgrade to SQLite3 Multiple Ciphers version 1.3.10 (SQLite version 3.38.2) * 4.7.8 - *March 2022* diff --git a/src/sqlite3mc_amalgamation.c b/src/sqlite3mc_amalgamation.c index f3ac736c..9dd8d43b 100644 --- a/src/sqlite3mc_amalgamation.c +++ b/src/sqlite3mc_amalgamation.c @@ -92,7 +92,7 @@ extern SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char*); /*** Begin of #include "sqlite3patched.c" ***/ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.38.2. By combining all the individual C code files into this +** version 3.38.3. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -544,9 +544,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.38.2" -#define SQLITE_VERSION_NUMBER 3038002 -#define SQLITE_SOURCE_ID "2022-03-26 13:51:10 d33c709cc0af66bc5b6dc6216eba9f1f0b40960b9ae83694c986fbf4c1d6f08f" +#define SQLITE_VERSION "3.38.3" +#define SQLITE_VERSION_NUMBER 3038003 +#define SQLITE_SOURCE_ID "2022-04-27 12:03:15 9547e2c38a1c6f751a77d4d796894dec4dc5d8f5d79b1cd39e1ffc50df7b3be4" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -20028,6 +20028,7 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); +SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr*,const SrcItem*); #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif @@ -29436,8 +29437,9 @@ SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const cha ** Free any prior content in *pz and replace it with a copy of zNew. */ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ + char *z = sqlite3DbStrDup(db, zNew); sqlite3DbFree(db, *pz); - *pz = sqlite3DbStrDup(db, zNew); + *pz = z; } /* @@ -67863,6 +67865,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ ** fragmented bytes within the page. */ memcpy(&aData[iAddr], &aData[pc], 2); aData[hdr+7] += (u8)x; + testcase( pc+x>maxPC ); + return &aData[pc]; }else if( x+pc > maxPC ){ /* This slot extends off the end of the usable part of the page */ *pRc = SQLITE_CORRUPT_PAGE(pPg); @@ -72062,7 +72066,7 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); assert( pPage->isInit ); if( pPage->leaf ){ - assert( pCur->ixpPage->nCell ); + assert( pCur->ixpPage->nCell || CORRUPT_DB ); pCur->ix = (u16)idx; *pRes = c; rc = SQLITE_OK; @@ -74586,7 +74590,7 @@ static int balance_nonroot( iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); - for(k=0; b.ixNx[k]<=i && ALWAYS(kflags&MEM_Str) || pMem->enc==desiredEnc ){ + if( !(pMem->flags&MEM_Str) ){ + pMem->enc = desiredEnc; + return SQLITE_OK; + } + if( pMem->enc==desiredEnc ){ return SQLITE_OK; } assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -104858,6 +104866,38 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ return exprIsConst(p, 3, iCur); } +/* +** Check pExpr to see if it is an invariant constraint on data source pSrc. +** This is an optimization. False negatives will perhaps cause slower +** queries, but false positives will yield incorrect answers. So when in +** double, return 0. +** +** To be an invariant constraint, the following must be true: +** +** (1) pExpr cannot refer to any table other than pSrc->iCursor. +** +** (2) pExpr cannot use subqueries or non-deterministic functions. +** +** (*) ** Not applicable to this branch ** +** +** (4) If pSrc is the right operand of a LEFT JOIN, then... +** (4a) pExpr must come from an ON clause.. +** (4b) and specifically the ON clause associated with the LEFT JOIN. +** +** (5) If pSrc is not the right operand of a LEFT JOIN or the left +** operand of a RIGHT JOIN, then pExpr must be from the WHERE +** clause, not an ON clause. +*/ +SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){ + if( pSrc->fg.jointype & JT_LEFT ){ + if( !ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (4a) */ + if( pExpr->w.iRightJoinTable!=pSrc->iCursor ) return 0; /* rule (4b) */ + }else{ + if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (5) */ + } + return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ +} + /* ** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy(). @@ -139146,8 +139186,7 @@ static int pushDownWhereTerms( Parse *pParse, /* Parse context (for malloc() and error reporting) */ Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ Expr *pWhere, /* The WHERE clause of the outer query */ - int iCursor, /* Cursor number of the subquery */ - int isLeftJoin /* True if pSubq is the right term of a LEFT JOIN */ + SrcItem *pSrc /* The subquery term of the outer FROM clause */ ){ Expr *pNew; int nChng = 0; @@ -139182,10 +139221,11 @@ static int pushDownWhereTerms( return 0; /* restriction (3) */ } while( pWhere->op==TK_AND ){ - nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, - iCursor, isLeftJoin); + nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrc); pWhere = pWhere->pLeft; } + +#if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */ if( isLeftJoin && (ExprHasProperty(pWhere,EP_FromJoin)==0 || pWhere->w.iRightJoinTable!=iCursor) @@ -139197,7 +139237,9 @@ static int pushDownWhereTerms( ){ return 0; /* restriction (5) */ } - if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ +#endif + + if( sqlite3ExprIsTableConstraint(pWhere, pSrc) ){ nChng++; pSubq->selFlags |= SF_PushDown; while( pSubq ){ @@ -139205,8 +139247,8 @@ static int pushDownWhereTerms( pNew = sqlite3ExprDup(pParse->db, pWhere, 0); unsetJoinExpr(pNew, -1); x.pParse = pParse; - x.iTable = iCursor; - x.iNewTable = iCursor; + x.iTable = pSrc->iCursor; + x.iNewTable = pSrc->iCursor; x.isLeftJoin = 0; x.pEList = pSubq->pEList; pNew = substExpr(&x, pNew); @@ -140988,8 +141030,7 @@ SQLITE_PRIVATE int sqlite3Select( if( OptimizationEnabled(db, SQLITE_PushDown) && (pItem->fg.isCte==0 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) - && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, - (pItem->fg.jointype & JT_OUTER)!=0) + && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem) ){ #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x100 ){ @@ -152914,8 +152955,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( ** WHERE clause (or the ON clause of a LEFT join) that constrain which ** rows of the target table (pSrc) that can be used. */ if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && ((pSrc->fg.jointype&JT_LEFT)==0 || ExprHasProperty(pExpr,EP_FromJoin)) - && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) + && sqlite3ExprIsTableConstraint(pExpr, pSrc) ){ pPartial = sqlite3ExprAnd(pParse, pPartial, sqlite3ExprDup(pParse->db, pExpr, 0)); @@ -153154,7 +153194,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( for(pTerm=pWInfo->sWC.a; pTermpExpr; if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && sqlite3ExprIsTableConstant(pExpr, iCur) + && sqlite3ExprIsTableConstraint(pExpr, pItem) ){ sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); } @@ -160074,7 +160114,7 @@ static void windowAggStep( for(iEnd=sqlite3VdbeCurrentAddr(v); iOpopcode==OP_Column && pOp->p1==pWin->iEphCsr ){ + if( pOp->opcode==OP_Column && pOp->p1==pMWin->iEphCsr ){ pOp->p1 = csr; } } @@ -194397,14 +194437,15 @@ static JsonNode *jsonLookupStep( *pzErr = zPath; return 0; } + testcase( nKey==0 ); }else{ zKey = zPath; for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} nKey = i; - } - if( nKey==0 ){ - *pzErr = zPath; - return 0; + if( nKey==0 ){ + *pzErr = zPath; + return 0; + } } j = 1; for(;;){ @@ -195552,6 +195593,33 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){ return SQLITE_OK; } +/* Append an object label to the JSON Path being constructed +** in pStr. +*/ +static void jsonAppendObjectPathElement( + JsonString *pStr, + JsonNode *pNode +){ + int jj, nn; + const char *z; + assert( pNode->eType==JSON_STRING ); + assert( pNode->jnFlags & JNODE_LABEL ); + assert( pNode->eU==1 ); + z = pNode->u.zJContent; + nn = pNode->n; + assert( nn>=2 ); + assert( z[0]=='"' ); + assert( z[nn-1]=='"' ); + if( nn>2 && sqlite3Isalpha(z[1]) ){ + for(jj=2; jjeType==JSON_OBJECT ); if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; - assert( pNode->eType==JSON_STRING ); - assert( pNode->jnFlags & JNODE_LABEL ); - assert( pNode->eU==1 ); - jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); + jsonAppendObjectPathElement(pStr, pNode); } } @@ -195650,8 +195715,7 @@ static int jsonEachColumn( if( p->eType==JSON_ARRAY ){ jsonPrintf(30, &x, "[%d]", p->iRowid); }else if( p->eType==JSON_OBJECT ){ - assert( pThis->eU==1 ); - jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); + jsonAppendObjectPathElement(&x, pThis); } } jsonResult(&x); @@ -234542,7 +234606,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2022-03-26 13:51:10 d33c709cc0af66bc5b6dc6216eba9f1f0b40960b9ae83694c986fbf4c1d6f08f", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2022-04-27 12:03:15 9547e2c38a1c6f751a77d4d796894dec4dc5d8f5d79b1cd39e1ffc50df7b3be4", -1, SQLITE_TRANSIENT); } /* @@ -239670,10 +239734,10 @@ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } #define SQLITE3MC_VERSION_H_ #define SQLITE3MC_VERSION_MAJOR 1 -#define SQLITE3MC_VERSION_MINOR 3 -#define SQLITE3MC_VERSION_RELEASE 10 +#define SQLITE3MC_VERSION_MINOR 4 +#define SQLITE3MC_VERSION_RELEASE 2 #define SQLITE3MC_VERSION_SUBRELEASE 0 -#define SQLITE3MC_VERSION_STRING "SQLite3 Multiple Ciphers 1.3.10" +#define SQLITE3MC_VERSION_STRING "SQLite3 Multiple Ciphers 1.4.2" #endif /* SQLITE3MC_VERSION_H_ */ /*** End of #include "sqlite3mc_version.h" ***/ @@ -239832,9 +239896,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.38.2" -#define SQLITE_VERSION_NUMBER 3038002 -#define SQLITE_SOURCE_ID "2022-03-26 13:51:10 d33c709cc0af66bc5b6dc6216eba9f1f0b40960b9ae83694c986fbf4c1d6f08f" +#define SQLITE_VERSION "3.38.3" +#define SQLITE_VERSION_NUMBER 3038003 +#define SQLITE_SOURCE_ID "2022-04-27 12:03:15 9547e2c38a1c6f751a77d4d796894dec4dc5d8f5d79b1cd39e1ffc50df7b3be4" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -262581,7 +262645,7 @@ sqlite3mcHandleMainKey(sqlite3* db, const char* zPath) ** Purpose: Implementation of SQLite codec API ** Author: Ulrich Telle ** Created: 2006-12-06 -** Copyright: (c) 2006-2021 Ulrich Telle +** Copyright: (c) 2006-2022 Ulrich Telle ** License: MIT */ @@ -262657,7 +262721,7 @@ sqlite3mcBtreeSetPageSize(Btree* p, int pageSize, int nReserve, int iFix) ** Change 4: Call sqlite3mcBtreeSetPageSize instead of sqlite3BtreeSetPageSize for main database ** (sqlite3mcBtreeSetPageSize allows to reduce the number of reserved bytes) ** -** This code is generated by the script rekeyvacuum.sh from SQLite version 3.38.2 amalgamation. +** This code is generated by the script rekeyvacuum.sh from SQLite version 3.38.3 amalgamation. */ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey( char **pzErrMsg, /* Write error message here */ @@ -263049,7 +263113,7 @@ SQLITE_PRIVATE Codec* sqlite3mcGetMainCodec(sqlite3* db); SQLITE_PRIVATE void -sqlite3mcSetCodec(sqlite3* db, const char* zFileName, Codec* codec); +sqlite3mcSetCodec(sqlite3* db, const char* zDbName, const char* zFileName, Codec* codec); static int mcAdjustBtree(Btree* pBt, int nPageSize, int nReserved, int isLegacy) @@ -263111,7 +263175,7 @@ sqlite3mcCodecAttach(sqlite3* db, int nDb, const char* zPath, const void* zKey, sqlite3mcSetBtree(codec, db->aDb[nDb].pBt); mcAdjustBtree(db->aDb[nDb].pBt, pageSize, reserved, sqlite3mcGetLegacyWriteCipher(codec)); sqlite3mcCodecSizeChange(codec, pageSize, reserved); - sqlite3mcSetCodec(db, dbFileName, codec); + sqlite3mcSetCodec(db, zDbName, dbFileName, codec); } else { @@ -263132,7 +263196,7 @@ sqlite3mcCodecAttach(sqlite3* db, int nDb, const char* zPath, const void* zKey, /* Remove codec for main database */ if (nDb == 0 && nKey == 0) { - sqlite3mcSetCodec(db, dbFileName, NULL); + sqlite3mcSetCodec(db, zDbName, dbFileName, NULL); } } } @@ -263167,7 +263231,7 @@ sqlite3mcCodecAttach(sqlite3* db, int nDb, const char* zPath, const void* zKey, int reserved = sqlite3mcGetReservedWriteCipher(codec); mcAdjustBtree(db->aDb[nDb].pBt, pageSize, reserved, sqlite3mcGetLegacyWriteCipher(codec)); sqlite3mcCodecSizeChange(codec, pageSize, reserved); - sqlite3mcSetCodec(db, dbFileName, codec); + sqlite3mcSetCodec(db, zDbName, dbFileName, codec); } else { @@ -263314,7 +263378,7 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) int nReservedWriteCipher; sqlite3mcSetHasReadCipher(codec, 0); /* Original database is not encrypted */ mcAdjustBtree(pBt, sqlite3mcGetPageSizeWriteCipher(codec), sqlite3mcGetReservedWriteCipher(codec), sqlite3mcGetLegacyWriteCipher(codec)); - sqlite3mcSetCodec(db, dbFileName, codec); + sqlite3mcSetCodec(db, zDbName, dbFileName, codec); nReservedWriteCipher = sqlite3mcGetReservedWriteCipher(codec); sqlite3mcCodecSizeChange(codec, nPagesize, nReservedWriteCipher); if (nReserved != nReservedWriteCipher) @@ -263465,7 +263529,7 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) if (!sqlite3mcIsEncrypted(codec)) { /* Remove codec for unencrypted database */ - sqlite3mcSetCodec(db, dbFileName, NULL); + sqlite3mcSetCodec(db, zDbName, dbFileName, NULL); } return rc; } @@ -273367,7 +273431,7 @@ int sqlite3_regexp_init( ** Purpose: Implementation of SQLite VFS for Multiple Ciphers ** Author: Ulrich Telle ** Created: 2020-02-28 -** Copyright: (c) 2020-2021 Ulrich Telle +** Copyright: (c) 2020-2022 Ulrich Telle ** License: MIT */ @@ -273396,6 +273460,7 @@ struct sqlite3mc_file { sqlite3_file base; /* sqlite3_file I/O methods */ sqlite3_file* pFile; /* Real underlying OS file */ + sqlite3mc_vfs* pVfsMC; /* Pointer to the sqlite3mc_vfs object */ const char* zFileName; /* File name */ int openFlags; /* Open flags */ sqlite3mc_file* pMainNext; /* Next main db file */ @@ -273418,9 +273483,6 @@ struct sqlite3mc_vfs #define REALVFS(p) ((sqlite3_vfs*)(((sqlite3mc_vfs*)(p))->base.pAppData)) #define REALFILE(p) (((sqlite3mc_file*)(p))->pFile) -#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) -#define ORIGFILE(p) ((sqlite3_file*)(((CksmFile*)(p))+1)) - /* ** Prototypes for VFS methods */ @@ -273474,37 +273536,8 @@ static const int walFrameHeaderSize = 24; static const int walFileHeaderSize = 32; /* -** Global VFS structure of SQLite3 Multiple Ciphers VFS +** Global I/O method structure of SQLite3 Multiple Ciphers VFS */ -static sqlite3mc_vfs mcVfsGlobal = -{ - { - 3, /* iVersion */ - 0, /* szOsFile */ - 1024, /* mxPathname */ - 0, /* pNext */ - SQLITE3MC_VFS_NAME, /* zName */ - 0, /* pAppData */ - mcVfsOpen, /* xOpen */ - mcVfsDelete, /* xDelete */ - mcVfsAccess, /* xAccess */ - mcVfsFullPathname, /* xFullPathname */ - mcVfsDlOpen, /* xDlOpen */ - mcVfsDlError, /* xDlError */ - mcVfsDlSym, /* xDlSym */ - mcVfsDlClose, /* xDlClose */ - mcVfsRandomness, /* xRandomness */ - mcVfsSleep, /* xSleep */ - mcVfsCurrentTime, /* xCurrentTime */ - mcVfsGetLastError, /* xGetLastError */ - mcVfsCurrentTimeInt64, /* xCurrentTimeInt64 */ - mcVfsSetSystemCall, /* xSetSystemCall */ - mcVfsGetSystemCall, /* xGetSystemCall */ - mcVfsNextSystemCall /* xNextSystemCall */ - }, - NULL -}; - static sqlite3_io_methods mcIoMethodsGlobal = { 3, /* iVersion */ @@ -273538,10 +273571,10 @@ static sqlite3_io_methods mcIoMethodsGlobal = static void mcMainListAdd(sqlite3mc_file* pFile) { assert( (pFile->openFlags & SQLITE_OPEN_MAIN_DB) ); - sqlite3_mutex_enter(mcVfsGlobal.mutex); - pFile->pMainNext = mcVfsGlobal.pMain; - mcVfsGlobal.pMain = pFile; - sqlite3_mutex_leave(mcVfsGlobal.mutex); + sqlite3_mutex_enter(pFile->pVfsMC->mutex); + pFile->pMainNext = pFile->pVfsMC->pMain; + pFile->pVfsMC->pMain = pFile; + sqlite3_mutex_leave(pFile->pVfsMC->mutex); } /* @@ -273550,11 +273583,11 @@ static void mcMainListAdd(sqlite3mc_file* pFile) static void mcMainListRemove(sqlite3mc_file* pFile) { sqlite3mc_file** pMainPrev; - sqlite3_mutex_enter(mcVfsGlobal.mutex); - for (pMainPrev = &mcVfsGlobal.pMain; *pMainPrev && *pMainPrev != pFile; pMainPrev = &((*pMainPrev)->pMainNext)){} + sqlite3_mutex_enter(pFile->pVfsMC->mutex); + for (pMainPrev = &pFile->pVfsMC->pMain; *pMainPrev && *pMainPrev != pFile; pMainPrev = &((*pMainPrev)->pMainNext)){} if (*pMainPrev) *pMainPrev = pFile->pMainNext; pFile->pMainNext = 0; - sqlite3_mutex_leave(mcVfsGlobal.mutex); + sqlite3_mutex_leave(pFile->pVfsMC->mutex); } /* @@ -273572,6 +273605,51 @@ static sqlite3mc_file* mcFindDbMainFileName(sqlite3mc_vfs* mcVfs, const char* zF return pDb; } +/* +** Find a pointer to the Multiple Ciphers VFS in use for a database connection. +*/ +static sqlite3mc_vfs* mcFindVfs(sqlite3* db, const char* zDbName) +{ + sqlite3mc_vfs* pVfsMC = NULL; + if (db->pVfs && db->pVfs->xOpen == mcVfsOpen) + { + /* The top level VFS is a Multiple Ciphers VFS */ + pVfsMC = (sqlite3mc_vfs*)(db->pVfs); + } + else + { + /* + ** The top level VFS is not a Multiple Ciphers VFS. + ** Retrieve the VFS names stack. + */ + char* zVfsNameStack = 0; + if ((sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsNameStack) == SQLITE_OK) && (zVfsNameStack != NULL)) + { + /* Search for the name prefix of a Multiple Ciphers VFS. */ + char* zVfsName = strstr(zVfsNameStack, SQLITE3MC_VFS_NAME); + if (zVfsName != NULL) + { + /* The prefix was found, now determine the full VFS name. */ + char* zVfsNameEnd = zVfsName + strlen(SQLITE3MC_VFS_NAME); + if (*zVfsNameEnd == '-') + { + for (++zVfsNameEnd; *zVfsNameEnd != '/' && *zVfsNameEnd != 0; ++zVfsNameEnd); + if (*zVfsNameEnd == '/') *zVfsNameEnd = 0; + + /* Find a pointer to the VFS with the determined name. */ + sqlite3_vfs* pVfs = sqlite3_vfs_find(zVfsName); + if (pVfs && pVfs->xOpen == mcVfsOpen) + { + pVfsMC = (sqlite3mc_vfs*) pVfs; + } + } + } + sqlite3_free(zVfsNameStack); + } + } + return pVfsMC; +} + /* ** Find the codec of the database file ** corresponding to the database schema name. @@ -273579,11 +273657,16 @@ static sqlite3mc_file* mcFindDbMainFileName(sqlite3mc_vfs* mcVfs, const char* zF SQLITE_PRIVATE Codec* sqlite3mcGetCodec(sqlite3* db, const char* zDbName) { Codec* codec = NULL; - const char* dbFileName = sqlite3_db_filename(db, zDbName); - sqlite3mc_file* pDbMain = mcFindDbMainFileName(&mcVfsGlobal, dbFileName); - if (pDbMain) + sqlite3mc_vfs* pVfsMC = mcFindVfs(db, zDbName); + + if (pVfsMC) { - codec = pDbMain->codec; + const char* dbFileName = sqlite3_db_filename(db, zDbName); + sqlite3mc_file* pDbMain = mcFindDbMainFileName(pVfsMC, dbFileName); + if (pDbMain) + { + codec = pDbMain->codec; + } } return codec; } @@ -273606,9 +273689,14 @@ SQLITE_PRIVATE Codec* sqlite3mcGetMainCodec(sqlite3* db) ** connection handle is actually valid, because the association between ** connection handles and database file handles is not maintained properly. */ -SQLITE_PRIVATE void sqlite3mcSetCodec(sqlite3* db, const char* zFileName, Codec* codec) +SQLITE_PRIVATE void sqlite3mcSetCodec(sqlite3* db, const char* zDbName, const char* zFileName, Codec* codec) { - sqlite3mc_file* pDbMain = mcFindDbMainFileName(&mcVfsGlobal, zFileName); + sqlite3mc_file* pDbMain = NULL; + sqlite3mc_vfs* pVfsMC = mcFindVfs(db, zDbName); + if (pVfsMC) + { + pDbMain = mcFindDbMainFileName((sqlite3mc_vfs*)(db->pVfs), zFileName); + } if (pDbMain) { Codec* prevCodec = pDbMain->codec; @@ -273677,6 +273765,7 @@ static int mcVfsOpen(sqlite3_vfs* pVfs, const char* zName, sqlite3_file* pFile, sqlite3mc_vfs* mcVfs = (sqlite3mc_vfs*) pVfs; sqlite3mc_file* mcFile = (sqlite3mc_file*) pFile; mcFile->pFile = (sqlite3_file*) &mcFile[1]; + mcFile->pVfsMC = mcVfs; mcFile->openFlags = flags; mcFile->zFileName = zName; mcFile->codec = 0; @@ -273707,7 +273796,7 @@ static int mcVfsOpen(sqlite3_vfs* pVfs, const char* zName, sqlite3_file* pFile, else if (flags & SQLITE_OPEN_MAIN_JOURNAL) { const char* dbFileName = sqlite3_filename_database(zName); - mcFile->pMainDb = mcFindDbMainFileName(&mcVfsGlobal, dbFileName); + mcFile->pMainDb = mcFindDbMainFileName(mcFile->pVfsMC, dbFileName); mcFile->zFileName = zName; SQLITE3MC_DEBUG_LOG("mcVfsOpen MAIN Journal: mcFile=%p fileName=%s dbFileName=%s\n", mcFile, mcFile->zFileName, dbFileName); } @@ -273722,7 +273811,7 @@ static int mcVfsOpen(sqlite3_vfs* pVfs, const char* zName, sqlite3_file* pFile, else if (flags & SQLITE_OPEN_SUBJOURNAL) { const char* dbFileName = sqlite3_filename_database(zName); - mcFile->pMainDb = mcFindDbMainFileName(&mcVfsGlobal, dbFileName); + mcFile->pMainDb = mcFindDbMainFileName(mcFile->pVfsMC, dbFileName); mcFile->zFileName = zName; SQLITE3MC_DEBUG_LOG("mcVfsOpen SUB Journal: mcFile=%p fileName=%s dbFileName=%s\n", mcFile, mcFile->zFileName, dbFileName); } @@ -273738,7 +273827,7 @@ static int mcVfsOpen(sqlite3_vfs* pVfs, const char* zName, sqlite3_file* pFile, else if (flags & SQLITE_OPEN_WAL) { const char* dbFileName = sqlite3_filename_database(zName); - mcFile->pMainDb = mcFindDbMainFileName(&mcVfsGlobal, dbFileName); + mcFile->pMainDb = mcFindDbMainFileName(mcFile->pVfsMC, dbFileName); mcFile->zFileName = zName; SQLITE3MC_DEBUG_LOG("mcVfsOpen WAL Journal: mcFile=%p fileName=%s dbFileName=%s\n", mcFile, mcFile->zFileName, dbFileName); } @@ -273860,7 +273949,7 @@ static int mcIoClose(sqlite3_file* pFile) p->codec = 0; } - assert(p->pMainNext == 0 && mcVfsGlobal.pMain != p); + assert(p->pMainNext == 0 && p->pVfsMC->pMain != p); rc = REALFILE(pFile)->pMethods->xClose(REALFILE(pFile)); return rc; } @@ -274522,6 +274611,14 @@ static int mcIoFileControl(sqlite3_file* pFile, int op, void* pArg) if (doReal) { rc = REALFILE(pFile)->pMethods->xFileControl(REALFILE(pFile), op, pArg); + if (rc == SQLITE_OK && op == SQLITE_FCNTL_VFSNAME) + { + sqlite3mc_vfs* pVfsMC = p->pVfsMC; + char* zIn = *(char**)pArg; + char* zOut = sqlite3_mprintf("%s/%z", pVfsMC->base.zName, zIn); + *(char**)pArg = zOut; + if (zOut == 0) rc = SQLITE_NOMEM; + } } return rc; } diff --git a/src/sqlite3mc_amalgamation.h b/src/sqlite3mc_amalgamation.h index c3a4bd62..9ae59970 100644 --- a/src/sqlite3mc_amalgamation.h +++ b/src/sqlite3mc_amalgamation.h @@ -30,10 +30,10 @@ #define SQLITE3MC_VERSION_H_ #define SQLITE3MC_VERSION_MAJOR 1 -#define SQLITE3MC_VERSION_MINOR 3 -#define SQLITE3MC_VERSION_RELEASE 10 +#define SQLITE3MC_VERSION_MINOR 4 +#define SQLITE3MC_VERSION_RELEASE 2 #define SQLITE3MC_VERSION_SUBRELEASE 0 -#define SQLITE3MC_VERSION_STRING "SQLite3 Multiple Ciphers 1.3.10" +#define SQLITE3MC_VERSION_STRING "SQLite3 Multiple Ciphers 1.4.2" #endif /* SQLITE3MC_VERSION_H_ */ /*** End of #include "sqlite3mc_version.h" ***/ @@ -192,9 +192,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.38.2" -#define SQLITE_VERSION_NUMBER 3038002 -#define SQLITE_SOURCE_ID "2022-03-26 13:51:10 d33c709cc0af66bc5b6dc6216eba9f1f0b40960b9ae83694c986fbf4c1d6f08f" +#define SQLITE_VERSION "3.38.3" +#define SQLITE_VERSION_NUMBER 3038003 +#define SQLITE_SOURCE_ID "2022-04-27 12:03:15 9547e2c38a1c6f751a77d4d796894dec4dc5d8f5d79b1cd39e1ffc50df7b3be4" /* ** CAPI3REF: Run-Time Library Version Numbers