From 7f42dcd901dee8ba5386cf02fa77f9d11617cd7d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 16 Nov 2020 18:45:21 +0000 Subject: [PATCH 1/3] Enhance the unix VFS so that it removes extra "/", "/./" and "/../" from the database filename. FossilOrigin-Name: 7ba89d3e5c68d970ed26c2ec6e6e34bae535c2cc0b22a022d20ac9ff4527b8ab --- manifest | 17 ++++++++------- manifest.uuid | 2 +- src/os_unix.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ test/shared.test | 8 +++---- 4 files changed, 68 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 8fefc6838d..ef27b4f759 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sdiagnostics\soutput\swith\s".wheretrace\s0x800".\s\sNo\schanges\sto\nnon-debug\sbuilds. -D 2020-11-12T18:16:01.196 +C Enhance\sthe\sunix\sVFS\sso\sthat\sit\sremoves\sextra\s"/",\s"/./"\sand\s"/../"\sfrom\nthe\sdatabase\sfilename. +D 2020-11-16T18:45:21.014 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -521,7 +521,7 @@ F src/os.c 80e4cf3e5da06be03ca641661e331ce60eeeeabf0d7354dbb1c0e166d0eedbbe F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c ff10667369f3b05aa697278a72d58fe7a43aaa674cb3fa9654d0fe21cda265d0 +F src/os_unix.c cd1ff5c1e49e8d9869a689ac40e626cb91c4f4a0aedb3c03bfaa22e6cfff12e2 F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 3700a1c55427a3d4168ad1f1b8a8b0cb9ace1d107e4506e30a8f1e66d8a1195e @@ -1334,7 +1334,7 @@ F test/server1.test c2b00864514a68a0e6fd518659dc95d0050307a357a08969872bef027d78 F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0c27ef896dbcb F test/sessionfuzz.c f74c4e806bab5a093fb9c11b6123d17a6e0cf73fb7a0f49b12f5a75bf0b7b1a8 -F test/shared.test 1826673eb5eb745fb91a3bdac99a7737057742ae38dcb0fe076a384d6727578b +F test/shared.test f022874d9d299fe913529dc10f52ad5a386e4e7ff709270b9b1111b3a0f3420a F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 F test/shared3.test ab693f9b6e156b8bfb2a0ad94f29fe69602a5d38 F test/shared4.test c75f476804e76e26bf6fa0e7b421fb0ca7d07558 @@ -1883,7 +1883,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 572f1ed59d29e74f810c74ef9e72ebc94c2d3e04befc03a1f88034f04a9c60a8 -R 4901674d935be395f9df3d7654b8445e +P 772ae83c61c87a9004a614d8ec120ba843286bff1edbd20b987fd592ced84d79 +R c29b95339ed23f814015f1859b8e38ba +T *branch * stronger-nofollow +T *sym-stronger-nofollow * +T -sym-trunk * U drh -Z 60f97595458aa54172137f4d47d1e884 +Z e93bd4a1cafad979ab0b42cbc7cacd32 diff --git a/manifest.uuid b/manifest.uuid index 3d1e246f07..07f0f8cdab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -772ae83c61c87a9004a614d8ec120ba843286bff1edbd20b987fd592ced84d79 \ No newline at end of file +7ba89d3e5c68d970ed26c2ec6e6e34bae535c2cc0b22a022d20ac9ff4527b8ab \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 6badcbd390..8846111ef7 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -6336,7 +6336,26 @@ static int unixAccess( } /* +** If the last component of the pathname in z[0]..z[j-1] is something +** other than ".." then back it out and return true. If the last +** component is empty or if it is ".." then return false. +*/ +static int unixBackupDir(const char *z, int *pJ){ + int j = *pJ; + int i; + if( j<=0 ) return 0; + for(i=j-1; i>0 && z[i-1]!='/'; i--){} + if( z[i]=='.' && i==j-2 && z[i+1]=='.' ) return 0; + *pJ = i-1; + return 1; +} + +/* +** Convert a relative pathname into a full pathname. Also +** simplify the pathname as follows: ** +** Remove all instances of /./ +** Remove all isntances of /X/../ for any X */ static int mkFullPathname( const char *zPath, /* Input path */ @@ -6345,6 +6364,7 @@ static int mkFullPathname( ){ int nPath = sqlite3Strlen30(zPath); int iOff = 0; + int i, j; if( zPath[0]!='/' ){ if( osGetcwd(zOut, nOut-2)==0 ){ return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); @@ -6359,6 +6379,40 @@ static int mkFullPathname( return SQLITE_CANTOPEN_BKPT; } sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); + + /* Remove duplicate '/' characters. Except, two // at the beginning + ** of a pathname is allowed since this is important on windows. */ + for(i=j=1; zOut[i]; i++){ + zOut[j++] = zOut[i]; + while( zOut[i]=='/' && zOut[i+1]=='/' ) i++; + } + zOut[j] = 0; + + for(i=j=0; zOut[i]; i++){ + if( zOut[i]=='/' ){ + /* Skip over internal "/." directory components */ + if( zOut[i+1]=='.' && zOut[i+2]=='/' ){ + i += 1; + continue; + } + + /* If this is a "/.." directory component then back out the + ** previous term of the directory if it is something other than "..". + */ + if( zOut[i+1]=='.' + && zOut[i+2]=='.' + && zOut[i+3]=='/' + && unixBackupDir(zOut, &j) + ){ + i += 2; + continue; + } + } + if( j>=0 ) zOut[j] = zOut[i]; + j++; + } + if( j==0 ) zOut[j++] = '/'; + zOut[j] = 0; return SQLITE_OK; } diff --git a/test/shared.test b/test/shared.test index 589df4d631..a0cd0a6696 100644 --- a/test/shared.test +++ b/test/shared.test @@ -160,11 +160,9 @@ do_test shared-$av.1.8 { } {} do_test shared-$av.2.1 { - # Open connection db3 to the database. Use a different path to the same - # file so that db3 does *not* share the same pager cache as db and db2 - # (there should be two open file handles). + # Open connection db3 to the database. if {$::tcl_platform(platform)=="unix"} { - sqlite3 db3 ./test.db + sqlite3 db3 "file:test.db?cache=private" -uri 1 } else { sqlite3 db3 TEST.DB } @@ -800,7 +798,7 @@ do_test shared-$av.10.3 { # An external connection should be able to read the database, but not # prepare a write operation. if {$::tcl_platform(platform)=="unix"} { - sqlite3 db3 ./test.db + sqlite3 db3 "file:test.db?cache=private" -uri 1 } else { sqlite3 db3 TEST.DB } From f4097026ef4c2c6fa7e528ac104fc7fce224a7d0 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 Nov 2020 20:07:24 +0000 Subject: [PATCH 2/3] Fix the tkt3793 test case so that work even when filenames are normalized. FossilOrigin-Name: e85d32ac6c82d39f5dc9b28f881d5d72f5e5a7e16df12c19315bfa8edea1b0b4 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- test/tkt3793.test | 15 ++------------- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index ef27b4f759..d73987de24 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sunix\sVFS\sso\sthat\sit\sremoves\sextra\s"/",\s"/./"\sand\s"/../"\sfrom\nthe\sdatabase\sfilename. -D 2020-11-16T18:45:21.014 +C Fix\sthe\stkt3793\stest\scase\sso\sthat\swork\seven\swhen\sfilenames\sare\snormalized. +D 2020-11-19T20:07:24.243 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1569,7 +1569,7 @@ F test/tkt3761.test b95ea9c98f21cf91325f18a984887e62caceab33 F test/tkt3762.test 4d439ff7abdc8d9323150269d182c37c2d514576 F test/tkt3773.test 7bca904d2a647a6a4a291bd86d7fd7c73855b789 F test/tkt3791.test a6624b9a80b216a26cf473607f42f3e51898c267 -F test/tkt3793.test d90ffd75c52413908d15e1c44fc2ea9c80fcc449 +F test/tkt3793.test ee95afaa8c950ec69c5410b2dd23e566099dbd452bdbfada1d726851b1607a0c F test/tkt3810.test 3a3be9965d1861bd84019875851ad5ea90fd8d76b638361514a36a48ea53191b F test/tkt3824.test 150aa00bb6220672e5f0eb14dc8eaa36750425f0 F test/tkt3832.test 2300d10d57562b89875b72148338ac3e14f8847d @@ -1883,10 +1883,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 772ae83c61c87a9004a614d8ec120ba843286bff1edbd20b987fd592ced84d79 -R c29b95339ed23f814015f1859b8e38ba -T *branch * stronger-nofollow -T *sym-stronger-nofollow * -T -sym-trunk * +P 7ba89d3e5c68d970ed26c2ec6e6e34bae535c2cc0b22a022d20ac9ff4527b8ab +R 40361254d6631e9816e560c440e5a0a0 U drh -Z e93bd4a1cafad979ab0b42cbc7cacd32 +Z 610ddd796adde40858f66c1214402146 diff --git a/manifest.uuid b/manifest.uuid index 07f0f8cdab..3dcc4301bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ba89d3e5c68d970ed26c2ec6e6e34bae535c2cc0b22a022d20ac9ff4527b8ab \ No newline at end of file +e85d32ac6c82d39f5dc9b28f881d5d72f5e5a7e16df12c19315bfa8edea1b0b4 \ No newline at end of file diff --git a/test/tkt3793.test b/test/tkt3793.test index 074aab2df0..62c0746078 100644 --- a/test/tkt3793.test +++ b/test/tkt3793.test @@ -13,7 +13,6 @@ # This file implements tests to verify that ticket #3793 has been # fixed. # -# $Id: tkt3793.test,v 1.2 2009/06/01 16:42:18 shane Exp $ set testdir [file dirname $argv0] @@ -26,18 +25,8 @@ ifcapable !shared_cache||!attach { set ::enable_shared_cache [sqlite3_enable_shared_cache 1] do_test tkt3793-1.1 { - # This is taken from shared.test. The Windows VFS expands - # ./test.db (and test.db) to be the same thing so the path - # matches and they share a cache. By changing the case - # for Windows platform, we get around this and get a separate - # connection. - if {$::tcl_platform(platform)=="unix"} { - sqlite3 db1 test.db - sqlite3 db2 test.db - } else { - sqlite3 db1 TEST.DB - sqlite3 db2 TEST.DB - } + sqlite3 db1 "file:test.db?cache=private" -uri 1 + sqlite3 db2 test.db execsql { BEGIN; CREATE TABLE t1(a, b); From e5dc4a2097352a013621b494faba154d9beb8488 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 Nov 2020 21:01:11 +0000 Subject: [PATCH 3/3] More test case changes so that shared-cache mode tests all work with normalized database names. FossilOrigin-Name: 6f0d5f0949130a4688319adf05d37c5ccd683ca9ad2dacb7ce433a5fe18ac3c3 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/shared3.test | 15 ++++++++------- test/tkt2854.test | 12 +----------- test/tkt3793.test | 4 +++- 5 files changed, 21 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index d73987de24..702a295477 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\stkt3793\stest\scase\sso\sthat\swork\seven\swhen\sfilenames\sare\snormalized. -D 2020-11-19T20:07:24.243 +C More\stest\scase\schanges\sso\sthat\sshared-cache\smode\stests\sall\swork\nwith\snormalized\sdatabase\snames. +D 2020-11-19T21:01:11.755 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1336,7 +1336,7 @@ F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0 F test/sessionfuzz.c f74c4e806bab5a093fb9c11b6123d17a6e0cf73fb7a0f49b12f5a75bf0b7b1a8 F test/shared.test f022874d9d299fe913529dc10f52ad5a386e4e7ff709270b9b1111b3a0f3420a F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 -F test/shared3.test ab693f9b6e156b8bfb2a0ad94f29fe69602a5d38 +F test/shared3.test f8cd07c1a2b7cdb315c01671a0b2f8e3830b11ef31da6baa9a9cd8da88965403 F test/shared4.test c75f476804e76e26bf6fa0e7b421fb0ca7d07558 F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9 F test/shared7.test a81e99f83e6c51b02ac99c96fb3a2a7b5978c956 @@ -1535,7 +1535,7 @@ F test/tkt2817.test f31839e01f4243cff7399ef654d3af3558cb8d8d F test/tkt2820.test 39940276b3436d125deb7d8ebeee053e4cf13213 F test/tkt2822.test f391776423a7c0d0949edfce375708bfb0f3141e F test/tkt2832.test a9b0b74a02dca166a04d9e37739c414b10929caa -F test/tkt2854.test e432965db29e27e16f539b2ba7f502eb2ccc49af +F test/tkt2854.test 47a2ae03bf36812f675ec06806a7b958e0de75312261dd8280c187f4a4a8281a F test/tkt2920.test a8737380e4ae6424e00c0273dc12775704efbebf F test/tkt2927.test 4752868b9eeeb07a217f7f19f4cbaac98d6d086d F test/tkt2942.test c5c87d179799ca6d1fbe83c815510b87cd5ec7ce @@ -1569,7 +1569,7 @@ F test/tkt3761.test b95ea9c98f21cf91325f18a984887e62caceab33 F test/tkt3762.test 4d439ff7abdc8d9323150269d182c37c2d514576 F test/tkt3773.test 7bca904d2a647a6a4a291bd86d7fd7c73855b789 F test/tkt3791.test a6624b9a80b216a26cf473607f42f3e51898c267 -F test/tkt3793.test ee95afaa8c950ec69c5410b2dd23e566099dbd452bdbfada1d726851b1607a0c +F test/tkt3793.test 9ee9c6f300adce634e8990a131ad5e20e22241643a1240c6b372b351205ef7cb F test/tkt3810.test 3a3be9965d1861bd84019875851ad5ea90fd8d76b638361514a36a48ea53191b F test/tkt3824.test 150aa00bb6220672e5f0eb14dc8eaa36750425f0 F test/tkt3832.test 2300d10d57562b89875b72148338ac3e14f8847d @@ -1883,7 +1883,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 7ba89d3e5c68d970ed26c2ec6e6e34bae535c2cc0b22a022d20ac9ff4527b8ab -R 40361254d6631e9816e560c440e5a0a0 +P e85d32ac6c82d39f5dc9b28f881d5d72f5e5a7e16df12c19315bfa8edea1b0b4 +R d6f4d784be7bd5d8f9c2ac433021e94e U drh -Z 610ddd796adde40858f66c1214402146 +Z f744e95c5d535aa2faa8ffb35a575ff0 diff --git a/manifest.uuid b/manifest.uuid index 3dcc4301bc..c7ad7d44cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e85d32ac6c82d39f5dc9b28f881d5d72f5e5a7e16df12c19315bfa8edea1b0b4 \ No newline at end of file +6f0d5f0949130a4688319adf05d37c5ccd683ca9ad2dacb7ce433a5fe18ac3c3 \ No newline at end of file diff --git a/test/shared3.test b/test/shared3.test index 1d09b69b82..e313069990 100644 --- a/test/shared3.test +++ b/test/shared3.test @@ -70,13 +70,14 @@ do_test shared3-2.5 { # test case shared3-2.3 above). The goal of the following tests is to # ensure that the cache-size really is 10 pages. # -if {$::tcl_platform(platform)=="unix"} { - set alternative_name ./test.db -} else { - set alternative_name TEST.DB -} +#if {$::tcl_platform(platform)=="unix"} { +# set alternative_name ./test.db +#} else { +# set alternative_name TEST.DB +#} do_test shared3-2.6 { - sqlite3 db3 $alternative_name + #sqlite3 db3 $alternative_name + sqlite3 db3 "file:./test.db?cache=private" -uri 1 catchsql {select count(*) from sqlite_master} db3 } {0 1} do_test shared3-2.7 { @@ -96,7 +97,7 @@ do_test shared3-2.8 { # statement above should have caused the pager to grab an exclusive lock # on the database file so that the cache could be spilled. # - catch { sqlite3 db3 $alternative_name } + catch { sqlite3 db3 "file:./test.db?cache=private" -uri 1 } catchsql {select count(*) from sqlite_master} db3 } {1 {database is locked}} diff --git a/test/tkt2854.test b/test/tkt2854.test index 914ddd1b69..e5ef2da7c0 100644 --- a/test/tkt2854.test +++ b/test/tkt2854.test @@ -28,17 +28,7 @@ set ::enable_shared_cache [sqlite3_enable_shared_cache 1] do_test tkt2854-1.1 { sqlite3 db test.db sqlite3 db2 test.db - - # This is taken from shared.test. The Windows VFS expands - # ./test.db (and test.db) to be the same thing so the path - # matches and they share a cache. By changing the case - # for Windows platform, we get around this and get a separate - # connection. - if {$::tcl_platform(platform)=="unix"} { - sqlite3 db3 ./test.db - } else { - sqlite3 db3 TEST.DB - } + sqlite3 db3 "file:test.db?cache=private" -uri 1 db eval { CREATE TABLE abc(a, b, c); diff --git a/test/tkt3793.test b/test/tkt3793.test index 62c0746078..07e47eb468 100644 --- a/test/tkt3793.test +++ b/test/tkt3793.test @@ -25,8 +25,10 @@ ifcapable !shared_cache||!attach { set ::enable_shared_cache [sqlite3_enable_shared_cache 1] do_test tkt3793-1.1 { + db close + sqlite3 db "file:test.db" -uri 1 sqlite3 db1 "file:test.db?cache=private" -uri 1 - sqlite3 db2 test.db + sqlite3 db2 "file:test.db?cache=shared" -uri 1 execsql { BEGIN; CREATE TABLE t1(a, b);