]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance the unix VFS so that it removes extra "/", "/./" and "/../" from
authordrh <drh@noemail.net>
Mon, 16 Nov 2020 18:45:21 +0000 (18:45 +0000)
committerdrh <drh@noemail.net>
Mon, 16 Nov 2020 18:45:21 +0000 (18:45 +0000)
the database filename.

FossilOrigin-Name: 7ba89d3e5c68d970ed26c2ec6e6e34bae535c2cc0b22a022d20ac9ff4527b8ab

manifest
manifest.uuid
src/os_unix.c
test/shared.test

index 8fefc6838d126b7be18108886eed67cf52c5f163..ef27b4f759436d04d09759f5a6ead4269956ff40 100644 (file)
--- 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
index 3d1e246f078aaa031b5861988021d808807bc3b7..07f0f8cdab9a44a623d63280bd84d37cafaac038 100644 (file)
@@ -1 +1 @@
-772ae83c61c87a9004a614d8ec120ba843286bff1edbd20b987fd592ced84d79
\ No newline at end of file
+7ba89d3e5c68d970ed26c2ec6e6e34bae535c2cc0b22a022d20ac9ff4527b8ab
\ No newline at end of file
index 6badcbd390c16ec64aafd6f4ff628a32296b4911..8846111ef7d7d3b7e7c6d2af9be9029ab519837a 100644 (file)
@@ -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;
 }
 
index 589df4d63178b15e73543948e201e9fd30ef0af5..a0cd0a66969aae055f48505f470f9ab1a838f3e3 100644 (file)
@@ -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
   }