]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Report an error if the main, or any other, database encoding is modified by an extern...
authordan <dan@noemail.net>
Thu, 5 Mar 2020 18:04:09 +0000 (18:04 +0000)
committerdan <dan@noemail.net>
Thu, 5 Mar 2020 18:04:09 +0000 (18:04 +0000)
FossilOrigin-Name: 895bd20b29e223496e1585483c6ce3335ae9050f2e5de4d6b69d0e40df396862

manifest
manifest.uuid
src/pragma.c
src/prepare.c
src/sqliteInt.h
test/enc.test

index a4b7c2fd0a2f68acb21d664ecde292e1db91c695..2f7d0852ef9979660fcc453a9fe4802b5571c139 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Change\sthe\ssqlite3.pDfltColl\s(the\sdefault\scollating\ssequence\sfor\sthe\ndatabase\sconnection)\sso\sthat\sit\sis\sthe\scollating\ssequence\sappropriate\sfor\nthe\sdatabase\sencoding,\snot\sthe\sUTF8\scollating\ssequence.\s\sThis\shelps\sto\nensure\sthat\sthe\sdatabase\sencoding\scollation\sis\salways\sused,\seven\sfor\nexpressions\sthat\sdo\snot\shave\san\sdefined\scollating\ssequence.\nTicket\s[1b8d7264567eb6fc].
-D 2020-03-05T16:13:24.200
+C Report\san\serror\sif\sthe\smain,\sor\sany\sother,\sdatabase\sencoding\sis\smodified\sby\san\sexternal\sprocess\s(perhaps\susing\sthe\sbackup\sAPI)\safter\sthe\sdb\shas\sbeen\sopened.
+D 2020-03-05T18:04:09.456
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -524,9 +524,9 @@ F src/parse.y 61ae75b1764c86f56fdfe384d736e4ba9b0d54015a5ca61925d8cb6b94943d4c
 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a
-F src/pragma.c 26a2d92028e69abbae7e58e5c40d360337de63bf7a4043299139298d50f4d9ab
+F src/pragma.c 5fd004b89c77319008ddff6d65dcc83ccca9584d3048f4f66b108b5906a20dba
 F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5
-F src/prepare.c d9b7b36b7ac5c07ba00fd3964ac6cff59b93a0b2c7d17ec27bb80c59975c1c64
+F src/prepare.c 8d4d6c8aa6afefc48027c54b41cdf134b4d6bc2fc4badbe483ad7fd9e1728a28
 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf
@@ -536,7 +536,7 @@ F src/shell.c.in 3897f3f7302914da1f6df3a2a09ac4aafa14a571d7d18c51500cfb2ff04f05e
 F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee
-F src/sqliteInt.h a02a77e59056fbe1cf8705e1149d817b54797bb41cacb114562bcc9ef431c735
+F src/sqliteInt.h 37511a5bd13dab6c61242b8d6525c7efdea7a90a7fd00e5ca8e809fa292efe7c
 F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -849,7 +849,7 @@ F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
 F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
 F test/e_walhook.test 01b494287ba9e60b70f6ebf3c6c62e0ffe01788e344a4846b08e5de0b344cb66
 F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62
-F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
+F test/enc.test 9a7be5479da985381d740b15f432800f65e2c87029ee57a318f42cb2eb43763a
 F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec
 F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6
 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
@@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P eb5c1b77d1c55fc286ff8fccfd61e21cb67aec92d6f93b093b9af5c32165d82b
-R 59b3562f907df451b0aff10dac9e4108
-U drh
-Z 48636fd7ed659b86f47f5ef00fcfb4ed
+P 4a5851893c3d71cc823b6ab5df5e58a852cd322fff26290f1ea05b63d67f564a
+R 74e2a598b7c2d32d296c9fb5e4ea1cd7
+U dan
+Z 79597c4800c4e22dc765415fcd19e860
index 75cb23563e852686c661b5aaeebe0bb6e9b4e70e..e558f20ced017f41b5cd01eb8ecfbc1fdda315a6 100644 (file)
@@ -1 +1 @@
-4a5851893c3d71cc823b6ab5df5e58a852cd322fff26290f1ea05b63d67f564a
\ No newline at end of file
+895bd20b29e223496e1585483c6ce3335ae9050f2e5de4d6b69d0e40df396862
\ No newline at end of file
index 504f51ec0f0c3f085fbb414f15be73b55fb7f48a..c5b5bb667009ee4fa304ab9f9c84b22fb791b07d 100644 (file)
@@ -1824,17 +1824,7 @@ void sqlite3Pragma(
       ** will be overwritten when the schema is next loaded. If it does not
       ** already exists, it will be created to use the new encoding value.
       */
-      int canChangeEnc = 1;  /* True if allowed to change the encoding */
-      int i;                 /* For looping over all attached databases */
-      for(i=0; i<db->nDb; i++){
-        if( db->aDb[i].pBt!=0
-         && DbHasProperty(db,i,DB_SchemaLoaded)
-         && !DbHasProperty(db,i,DB_Empty)
-        ){
-          canChangeEnc = 0;
-        }
-      }
-      if( canChangeEnc ){
+      if( (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){
         for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
           if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
             u8 enc = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
index 67995f33ce2513d9043aadaa53699300946300cb..228d14876e48cc2fb6b1b6f3497c472fb163e2a5 100644 (file)
@@ -91,7 +91,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
   assert( argc==5 );
   UNUSED_PARAMETER2(NotUsed, argc);
   assert( sqlite3_mutex_held(db->mutex) );
-  DbClearProperty(db, iDb, DB_Empty);
+  db->mDbFlags |= DBFLAG_EncodingFixed;
   pData->nInitRow++;
   if( db->mallocFailed ){
     corruptSchema(pData, argv[1], 0);
@@ -179,6 +179,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
   InitData initData;
   const char *zMasterName;
   int openedTransaction = 0;
+  int mask = ((db->mDbFlags & DBFLAG_EncodingFixed) | ~DBFLAG_EncodingFixed);
 
   assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 );
   assert( iDb>=0 && iDb<db->nDb );
@@ -207,6 +208,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
   initData.mInitFlags = mFlags;
   initData.nInitRow = 0;
   sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
+  db->mDbFlags &= mask;
   if( initData.rc ){
     rc = initData.rc;
     goto error_out;
@@ -266,7 +268,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
   ** as sqlite3.enc.
   */
   if( meta[BTREE_TEXT_ENCODING-1] ){  /* text encoding */
-    if( iDb==0 ){
+    if( iDb==0 && (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){
       u8 encoding;
 #ifndef SQLITE_OMIT_UTF16
       /* If opening the main database, set ENC(db). */
@@ -278,15 +280,13 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
       sqlite3SetTextEncoding(db, encoding);
     }else{
       /* If opening an attached database, the encoding much match ENC(db) */
-      if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
+      if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){
         sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
             " text encoding as main database");
         rc = SQLITE_ERROR;
         goto initone_error_out;
       }
     }
-  }else{
-    DbSetProperty(db, iDb, DB_Empty);
   }
   pDb->pSchema->enc = ENC(db);
 
@@ -398,8 +398,7 @@ error_out:
 ** error occurs, write an error message into *pzErrMsg.
 **
 ** After a database is initialized, the DB_SchemaLoaded bit is set
-** bit is set in the flags field of the Db structure. If the database
-** file was of zero-length, then the DB_Empty flag is also set.
+** bit is set in the flags field of the Db structure. 
 */
 int sqlite3Init(sqlite3 *db, char **pzErrMsg){
   int i, rc;
index 814a7d8061ef29d708242a66440f5f66abac7ca5..c338dabca196b04a0c0c3975fb03a0a5483ddedf 100644 (file)
@@ -1264,7 +1264,6 @@ struct Schema {
 */
 #define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
 #define DB_UnresetViews    0x0002  /* Some views have defined column names */
-#define DB_Empty           0x0004  /* The file is empty (length 0 bytes) */
 #define DB_ResetWanted     0x0008  /* Reset the schema when nSchemaLock==0 */
 
 /*
@@ -1631,6 +1630,7 @@ struct sqlite3 {
 #define DBFLAG_VacuumInto     0x0008  /* Currently running VACUUM INTO */
 #define DBFLAG_SchemaKnownOk  0x0010  /* Schema is known to be valid */
 #define DBFLAG_InternalFunc   0x0020  /* Allow use of internal functions */
+#define DBFLAG_EncodingFixed  0x0040  /* No longer possible to change enc. */
 
 /*
 ** Bits of the sqlite3.dbOptFlags field that are used by the
index 5c24bbb7f65f634365a5c0b4c49c3289b752811c..ffe24164bd225e36f3842e5d50262f035872af2a 100644 (file)
@@ -169,4 +169,84 @@ do_test enc-11.2 {
   }
 } {2}
 
+#-------------------------------------------------------------------------
+reset_db
+forcedelete test.db2
+forcedelete test.db3
+
+do_execsql_test enc-12.0 {
+  PRAGMA encoding = 'utf-8';
+  CREATE TABLE t1(a, b, c);
+  INSERT INTO t1 VALUES('a', 'b', 'c');
+  ATTACH 'test.db3' AS aux;
+  CREATE TABLE aux.t3(x, y, z);
+  INSERT INTO t3 VALUES('xxx', 'yyy', 'zzz');
+  PRAGMA encoding;
+} {UTF-8}
+
+do_test enc-12.1 {
+  sqlite3 db2 test.db2
+  db2 eval {
+    PRAGMA encoding = 'UTF-16le';
+    CREATE TABLE t2(d, e, f);
+    INSERT INTO t2 VALUES('d', 'e', 'f');
+    PRAGMA encoding;
+  }
+} {UTF-16le}
+
+do_test enc-12.2 {
+  db2 backup test.db
+  db2 close
+} {}
+
+do_catchsql_test enc-12.3 {
+  SELECT * FROM t2;
+} {1 {attached databases must use the same text encoding as main database}}
+
+db close
+sqlite3 db test.db3
+do_execsql_test enc-12.4 {
+  SELECT * FROM t3;
+  PRAGMA encoding = 'UTF-16le';
+  SELECT * FROM t3;
+} {xxx yyy zzz xxx yyy zzz}
+
+db close
+sqlite3 db test.db3
+breakpoint
+do_execsql_test enc-12.5 {
+  PRAGMA encoding = 'UTF-16le';
+  PRAGMA encoding;
+} {UTF-8}
+
+reset_db
+do_execsql_test enc-12.6 {
+  PRAGMA encoding = 'UTF-8';
+  CREATE TEMP TABLE t1(a, b, c);
+  INSERT INTO t1 VALUES('xxx', 'yyy', 'zzz');
+}
+do_test enc-12.7 {
+  sqlite3 db2 test.db2
+  db2 backup test.db
+  db2 close
+  db eval {
+    SELECT * FROM t1;
+  }
+} {xxx yyy zzz}
+do_catchsql_test enc-12.8 {
+  SELECT * FROM t2;
+  SELECT * FROM t1;
+} {1 {attached databases must use the same text encoding as main database}}
+
+db close
+sqlite3 db test.db
+do_execsql_test enc-12.9 {
+  CREATE TEMP TABLE t1(a, b, c);
+  INSERT INTO t1 VALUES('xxx', 'yyy', 'zzz');
+}
+do_execsql_test enc-12.10 {
+  SELECT * FROM t2;
+  SELECT * FROM t1;
+} {d e f xxx yyy zzz}
+
 finish_test