aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <Dan Kennedy>2023-01-20 17:50:24 +0000
committerdan <Dan Kennedy>2023-01-20 17:50:24 +0000
commitd993b15aa3615ef0cf8e8117156b00b03d65c1bf (patch)
treeb1155f2e0fcb1dda849ff3290552530619313390 /src
parentab5ebc4082512721f3a6d24b101225dab7b4b472 (diff)
downloadsqlite-d993b15aa3615ef0cf8e8117156b00b03d65c1bf.tar.gz
sqlite-d993b15aa3615ef0cf8e8117156b00b03d65c1bf.zip
Ensure that the database encoding cannot be changed while there are statements running. And that the connection is left in a valid state after an obscure OOM within sqlite3_deserialize().
FossilOrigin-Name: a02da71f3a80dd8e817e89cdaa775c95e38c90d2471f8fec516bed086539e2c0
Diffstat (limited to 'src')
-rw-r--r--src/attach.c25
-rw-r--r--src/prepare.c7
2 files changed, 26 insertions, 6 deletions
diff --git a/src/attach.c b/src/attach.c
index 1732be27b..917fcad67 100644
--- a/src/attach.c
+++ b/src/attach.c
@@ -105,13 +105,26 @@ static void attachFunc(
/* This is not a real ATTACH. Instead, this routine is being called
** from sqlite3_deserialize() to close database db->init.iDb and
** reopen it as a MemDB */
+ Btree *pNewBt = 0;
pVfs = sqlite3_vfs_find("memdb");
if( pVfs==0 ) return;
- pNew = &db->aDb[db->init.iDb];
- if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
- pNew->pBt = 0;
- pNew->pSchema = 0;
- rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
+ rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB);
+ if( rc==SQLITE_OK ){
+ Schema *pNewSchema = sqlite3SchemaGet(db, pNewBt);
+ if( pNewSchema ){
+ /* Both the Btree and the new Schema were allocated successfully.
+ ** Close the old db and update the aDb[] slot with the new memdb
+ ** values. */
+ pNew = &db->aDb[db->init.iDb];
+ if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
+ pNew->pBt = pNewBt;
+ pNew->pSchema = pNewSchema;
+ }else{
+ sqlite3BtreeClose(pNewBt);
+ rc = SQLITE_NOMEM;
+ }
+ }
+ if( rc ) goto attach_error;
}else{
/* This is a real ATTACH
**
@@ -341,6 +354,8 @@ static void codeAttach(
sqlite3* db = pParse->db;
int regArgs;
+ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto attach_end;
+
if( pParse->nErr ) goto attach_end;
memset(&sName, 0, sizeof(NameContext));
sName.pParse = pParse;
diff --git a/src/prepare.c b/src/prepare.c
index 760738740..b2613e2c1 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -306,7 +306,12 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
#else
encoding = SQLITE_UTF8;
#endif
- sqlite3SetTextEncoding(db, encoding);
+ if( db->nVdbeActive>0 && encoding!=ENC(db) ){
+ rc = SQLITE_LOCKED;
+ goto initone_error_out;
+ }else{
+ sqlite3SetTextEncoding(db, encoding);
+ }
}else{
/* If opening an attached database, the encoding much match ENC(db) */
if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){