-C Fix\san\soff-by-one\serror\sin\sthe\snew\ssqlite3_uri_parameter()\sfunction.
-D 2011-05-17T19:43:38.641
+C Add\sthe\sability\sto\slimit\sfilenames\sto\s8+3\susing\sthe\nSQLITE_ENABLE_8_3_NAMES\scompile-time\soption\stogether\swith\sa\sURI\nparameter\sof\s"8_3_names=1".
+D 2011-05-17T20:36:21.474
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
-F src/os_unix.c 2c67d126874b78eb427371db4793f0e8fbc7448b
-F src/os_win.c ff0e14615a5086fa5ba6926e4ec0dc9cfb5a1a84
-F src/pager.c ebf0411b037fbc6dec272520be55fc11423e789a
+F src/os_unix.c 6d4a58d81ad4b782406519f3790202f330e89bb7
+F src/os_win.c 218b899469e570d46eb8147c2383075f7c026230
+F src/pager.c b7fe4b8e51d51a062618c4630c40d20a1a44cb80
F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e
-F src/pragma.c 49c90ab27a4339d4b5bc0b03c08cbcf20ed8d454
+F src/pragma.c 9e778decc3ee9bcaf88904b4a3b0a4360aaf0eab
F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/shell.c 72e7e176bf46d5c6518d15ac4ad6847c4bb5df79
F src/sqlite.h.in 8bbf8d9bc5f1a9474a633a2de7014506f1f06b90
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
-F src/sqliteInt.h b34bd64a7ade4808fcc301e0bb67ef5051ea49c6
+F src/sqliteInt.h 771087591052966d36ac1fcd3c8bb7a8c6cf9a38
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
-F src/test_config.c d536042f27226b4639f0f87d4795fd37428a9ddf
+F src/test_config.c 9a6aa8301a56906612b5e70f5b38e80cfb8af8e7
F src/test_demovfs.c 938d0f595f8bd310076e1c06cf7885a01ce7ce01
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5
F src/trigger.c 144cc18bb701f3286484aae4292a9531f09278c8
F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f
F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60
-F src/util.c 914e860d21496b19a912cd14f6f7a889a22f44e1
+F src/util.c 5f4ba293a4bce63aab6885edde6261b007b34a20
F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e
F src/vdbe.c 343a068e8daeb8475e66776feb9f2974046e95c5
F src/vdbe.h 8a675fefdf7119441fe817c800a9a52440c2e797
F src/vdbeInt.h fe8f58d305e629fff02f61f655aca1d299f1f6ae
F src/vdbeapi.c e0e2672e0a96ae3f8575c8ecd02912a3e8a554a1
-F src/vdbeaux.c 25aa5ba7d46b4fe7c8f33dc132d474242d5f9726
+F src/vdbeaux.c 535851211df61d83213c83d5ffd3c6ce9ecbdc18
F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562
F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b
F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114
F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
F src/where.c 55403ce19c506be6a321c7f129aff693d6103db5
+F test/8_3_names.test b93687beebd17f6ebf812405a6833bae5d1f4199
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 51756962d522e474338e9b2ebb26e7364d4aa125
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 6b5de95fb575c7ceb3034068c4f5e0fccb1b15ac
-R d104cfa9424db95a1c8ed2af31b70a54
+P 9593a640795458ce6e57e02dd5d702b642858f76
+R 87dd50ad185017288f71d71ad9ceabb5
U drh
-Z e3568578d123c11b9aea2de4d2897b24
+Z 1ba151bdfae18403ba429fed62365eed
-9593a640795458ce6e57e02dd5d702b642858f76
\ No newline at end of file
+96d609856025919571f781207dfa6a24b1732e8d
\ No newline at end of file
(u32)sStat.st_ino, (u32)sStat.st_dev);
#else
sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
+ sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
#endif
pShmNode->h = -1;
pDbFd->pInode->pShmNode = pShmNode;
** corresponding database file and sets *pMode to this value. Whenever
** possible, WAL and journal files are created using the same permissions
** as the associated database file.
+**
+** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the
+** original filename is unavailable. But 8_3_NAMES is only used for
+** FAT filesystems and permissions do not matter there, so just use
+** the default permissions.
*/
static int findCreateFileMode(
const char *zPath, /* Path of file (possibly) being created */
mode_t *pMode /* OUT: Permissions to open file with */
){
int rc = SQLITE_OK; /* Return Code */
+ *pMode = SQLITE_DEFAULT_FILE_PERMISSIONS;
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
char zDb[MAX_PATHNAME+1]; /* Database file path */
int nDb; /* Number of valid bytes in zDb */
**
** "<path to db>-journal"
** "<path to db>-wal"
- ** "<path to db>-journal-NNNN"
- ** "<path to db>-wal-NNNN"
+ ** "<path to db>-journalNN"
+ ** "<path to db>-walNN"
**
- ** where NNNN is a 4 digit decimal number. The NNNN naming schemes are
+ ** where NN is a 4 digit decimal number. The NN naming schemes are
** used by the test_multiplex.c module.
*/
nDb = sqlite3Strlen30(zPath) - 1;
- while( nDb>0 && zPath[nDb]!='l' ) nDb--;
- nDb -= ((flags & SQLITE_OPEN_WAL) ? 3 : 7);
+ while( nDb>0 && zPath[nDb]!='-' ) nDb--;
+ if( nDb==0 ) return SQLITE_OK;
memcpy(zDb, zPath, nDb);
zDb[nDb] = '\0';
}
}else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
*pMode = 0600;
- }else{
- *pMode = SQLITE_DEFAULT_FILE_PERMISSIONS;
}
return rc;
}
memset(pNew, 0, sizeof(*pNew));
pNew->zFilename = (char*)&pNew[1];
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
+ sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
/* Look to see if there is an existing winShmNode that can be used.
** If no matching winShmNode currently exists, create a new one.
memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
memcpy(pPager->zJournal, zPathname, nPathname);
memcpy(&pPager->zJournal[nPathname], "-journal", 8);
+ sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
#ifndef SQLITE_OMIT_WAL
pPager->zWal = &pPager->zJournal[nPathname+8+1];
memcpy(pPager->zWal, zPathname, nPathname);
memcpy(&pPager->zWal[nPathname], "-wal", 4);
+ sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
#endif
sqlite3_free(zPathname);
}
/*
** Interpret the given string as a boolean value.
*/
-static u8 getBoolean(const char *z){
+u8 sqlite3GetBoolean(const char *z){
return getSafetyLevel(z)&1;
}
mask &= ~(SQLITE_ForeignKeys);
}
- if( getBoolean(zRight) ){
+ if( sqlite3GetBoolean(zRight) ){
db->flags |= mask;
}else{
db->flags &= ~mask;
int b = -1;
assert( pBt!=0 );
if( zRight ){
- b = getBoolean(zRight);
+ b = sqlite3GetBoolean(zRight);
}
if( pId2->n==0 && b>=0 ){
int ii;
#ifndef NDEBUG
if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
if( zRight ){
- if( getBoolean(zRight) ){
+ if( sqlite3GetBoolean(zRight) ){
sqlite3ParserTrace(stderr, "parser: ");
}else{
sqlite3ParserTrace(0, 0);
*/
if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){
if( zRight ){
- sqlite3RegisterLikeFunctions(db, getBoolean(zRight));
+ sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight));
}
}else
int sqlite3SubInt64(i64*,i64);
int sqlite3MulInt64(i64*,i64);
int sqlite3AbsInt32(int);
+#ifdef SQLITE_ENABLE_8_3_NAMES
+void sqlite3FileSuffix3(const char*, char*);
+#else
+# define sqlite3FileSuffix3(X,Y)
+#endif
+u8 sqlite3GetBoolean(const char *z);
const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueBytes(sqlite3_value*, u8);
Tcl_SetVar2(interp, "sqlite_options", "memdebug", "0", TCL_GLOBAL_ONLY);
#endif
+#ifdef SQLITE_ENABLE_8_3_NAMES
+ Tcl_SetVar2(interp, "sqlite_options", "8_3_names", "1", TCL_GLOBAL_ONLY);
+#else
+ Tcl_SetVar2(interp, "sqlite_options", "8_3_names", "0", TCL_GLOBAL_ONLY);
+#endif
+
#ifdef SQLITE_ENABLE_MEMSYS3
Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY);
#else
if( x==(int)0x80000000 ) return 0x7fffffff;
return -x;
}
+
+#ifdef SQLITE_ENABLE_8_3_NAMES
+/*
+** If SQLITE_ENABLE_8_3_NAME is set at compile-time and if the database
+** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and
+** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
+** three characters, then shorten the suffix on z[] to be the last three
+** characters of the original suffix.
+**
+** Examples:
+**
+** test.db-journal => test.nal
+** test.db-wal => test.wal
+** test.db-shm => test.shm
+*/
+void sqlite3FileSuffix3(const char *zBaseFilename, char *z){
+ const char *zOk;
+ zOk = sqlite3_uri_parameter(zBaseFilename, "8_3_names");
+ if( zOk && sqlite3GetBoolean(zOk) ){
+ int i, sz;
+ sz = sqlite3Strlen30(z);
+ for(i=sz-1; i>0 && z[i]!='/' && z[i]!='\\' && z[i]!='.'; i--){}
+ if( z[i]=='.' && sz>i+4 ) memcpy(&z[i+1], &z[sz-3], 4);
+ }
+}
+#endif
if( !zMaster ){
return SQLITE_NOMEM;
}
+ sqlite3FileSuffix3(zMainFile, zMaster);
rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
}while( rc==SQLITE_OK && res );
if( rc==SQLITE_OK ){
--- /dev/null
+# 2011 May 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.
+#
+#***********************************************************************
+#
+# Test cases for the SQLITE_ENABLE_8_3_NAMES feature that forces all
+# filename extensions to be limited to 3 characters. Some embedded
+# systems need this to work around microsoft FAT patents, but this
+# feature should be disabled on most deployments.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+ifcapable !8_3_names {
+ finish_test
+ return
+}
+
+db close
+sqlite3_shutdown
+sqlite3_config_uri 1
+
+do_test 8_3_names-1.0 {
+ forcedelete test.db test.nal test.db-journal
+ sqlite3 db test.db
+ db eval {
+ PRAGMA cache_size=10;
+ CREATE TABLE t1(x);
+ INSERT INTO t1 VALUES(randomblob(20000));
+ BEGIN;
+ DELETE FROM t1;
+ INSERT INTO t1 VALUES(randomblob(15000));
+ }
+ file exists test.db-journal
+} 1
+do_test 8_3_names-1.1 {
+ file exists test.nal
+} 0
+do_test 8_3_names-1.2 {
+ db eval {
+ ROLLBACK;
+ SELECT length(x) FROM t1
+ }
+} 20000
+
+db close
+do_test 8_3_names-2.0 {
+ forcedelete test.db test.nal test.db-journal
+ sqlite3 db file:./test.db?8_3_names=1
+ db eval {
+ PRAGMA cache_size=10;
+ CREATE TABLE t1(x);
+ INSERT INTO t1 VALUES(randomblob(20000));
+ BEGIN;
+ DELETE FROM t1;
+ INSERT INTO t1 VALUES(randomblob(15000));
+ }
+ file exists test.db-journal
+} 0
+do_test 8_3_names-2.1 {
+ file exists test.nal
+} 1
+forcedelete test2.db test2.nal test2.db-journal
+file copy test.db test2.db
+file copy test.nal test2.nal
+do_test 8_3_names-2.2 {
+ db eval {
+ COMMIT;
+ SELECT length(x) FROM t1
+ }
+} 15000
+do_test 8_3_names-2.3 {
+ sqlite3 db2 file:./test2.db?8_3_names=1
+ db2 eval {
+ PRAGMA integrity_check;
+ SELECT length(x) FROM t1;
+ }
+} {ok 20000}
+
+db close
+do_test 8_3_names-3.0 {
+ forcedelete test.db test.nal test.db-journal
+ sqlite3 db file:./test.db?8_3_names=0
+ db eval {
+ PRAGMA cache_size=10;
+ CREATE TABLE t1(x);
+ INSERT INTO t1 VALUES(randomblob(20000));
+ BEGIN;
+ DELETE FROM t1;
+ INSERT INTO t1 VALUES(randomblob(15000));
+ }
+ file exists test.db-journal
+} 1
+do_test 8_3_names-3.1 {
+ file exists test.nal
+} 0
+forcedelete test2.db test2.nal test2.db-journal
+file copy test.db test2.db
+file copy test.db-journal test2.db-journal
+do_test 8_3_names-3.2 {
+ db eval {
+ COMMIT;
+ SELECT length(x) FROM t1
+ }
+} 15000
+do_test 8_3_names-3.3 {
+ sqlite3 db2 file:./test2.db?8_3_names=0
+ db2 eval {
+ PRAGMA integrity_check;
+ SELECT length(x) FROM t1;
+ }
+} {ok 20000}
+
+##########################################################################
+# Master journals.
+#
+db close
+forcedelete test.db test2.db
+do_test 8_3_names-4.0 {
+ sqlite3 db file:./test.db?8_3_names=1
+ db eval {
+ CREATE TABLE t1(x);
+ INSERT INTO t1 VALUES(1);
+ ATTACH 'file:./test2.db?8_3_names=1' AS db2;
+ CREATE TABLE db2.t2(y);
+ INSERT INTO t2 VALUES(2);
+ BEGIN;
+ INSERT INTO t1 VALUES(3);
+ INSERT INTO t2 VALUES(4);
+ COMMIT;
+ SELECT * FROM t1, t2 ORDER BY x, y
+ }
+} {1 2 1 4 3 2 3 4}
+
+
+##########################################################################
+# WAL mode.
+#
+ifcapable !wal {
+ finish_test
+ return
+}
+db close
+forcedelete test.db
+do_test 8_3_names-5.0 {
+ sqlite3 db file:./test.db?8_3_names=1
+ register_wholenumber_module db
+ db eval {
+ PRAGMA journal_mode=WAL;
+ CREATE TABLE t1(x);
+ CREATE VIRTUAL TABLE nums USING wholenumber;
+ INSERT INTO t1 SELECT value FROM nums WHERE value BETWEEN 1 AND 1000;
+ BEGIN;
+ UPDATE t1 SET x=x*2;
+ }
+ sqlite3 db2 file:./test.db?8_3_names=1
+ register_wholenumber_module db2
+ db2 eval {
+ BEGIN;
+ SELECT sum(x) FROM t1;
+ }
+} {500500}
+
+do_test 8_3_names-5.1 {
+ file exists test.db-wal
+} 0
+do_test 8_3_names-5.2 {
+ file exists test.wal
+} 1
+do_test 8_3_names-5.3 {
+ file exists test.db-shm
+} 0
+do_test 8_3_names-5.4 {
+ file exists test.shm
+} 1
+
+
+do_test 8_3_names-5.5 {
+ db eval {
+ COMMIT;
+ SELECT sum(x) FROM t1;
+ }
+} {1001000}
+do_test 8_3_names-5.6 {
+ db2 eval {
+ SELECT sum(x) FROM t1;
+ }
+} {500500}
+
+
+finish_test