aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2020-01-27 14:40:44 +0000
committerdrh <drh@noemail.net>2020-01-27 14:40:44 +0000
commit532b0d23fd80082a8706ec683b1c7afed26ee6c4 (patch)
tree0bb03e9102158f00f5409e974a250b3ac5d74283 /src/main.c
parent9a3bdeba3e87de596e0a97ac84319183d6fc557f (diff)
downloadsqlite-532b0d23fd80082a8706ec683b1c7afed26ee6c4.tar.gz
sqlite-532b0d23fd80082a8706ec683b1c7afed26ee6c4.zip
Revise the layout of filenames in the Pager object so that it is unchanged
from prior versions. It turns out that some important 3rd-party software does questionable pointer manipulations on those filenames that depend on that legacy layout. Technical this is a misuse of SQLite by the 3rd-party software, but we want to avoid unnecessary breakage. FossilOrigin-Name: 34ab760689fd493eda482e856047708d74e769a01cc90b69da456d79ffe39aea
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c54
1 files changed, 32 insertions, 22 deletions
diff --git a/src/main.c b/src/main.c
index 903f187a9..3983f083b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4244,6 +4244,21 @@ int sqlite3_test_control(int op, ...){
}
/*
+** The Pager stores the Database filename, Journal filename, and WAL filename
+** consecutively in memory, in that order. The database filename is prefixed
+** by four zero bytes. Locate the start of the database filename by searching
+** backwards for the first byte following four consecutive zero bytes.
+**
+** This only works if the filename passed in was obtained from the Pager.
+*/
+static const char *databaseName(const char *zName){
+ while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
+ zName--;
+ }
+ return zName;
+}
+
+/*
** This is a utility routine, useful to VFS implementations, that checks
** to see if a database file was a URI that contained a specific query
** parameter, and if so obtains the value of the query parameter.
@@ -4256,6 +4271,7 @@ int sqlite3_test_control(int op, ...){
*/
const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
if( zFilename==0 || zParam==0 ) return 0;
+ zFilename = databaseName(zFilename);
zFilename += sqlite3Strlen30(zFilename) + 1;
while( zFilename[0] ){
int x = strcmp(zFilename, zParam);
@@ -4271,6 +4287,7 @@ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
*/
const char *sqlite3_uri_key(const char *zFilename, int N){
if( zFilename==0 || N<0 ) return 0;
+ zFilename = databaseName(zFilename);
zFilename += sqlite3Strlen30(zFilename) + 1;
while( zFilename[0] && (N--)>0 ){
zFilename += sqlite3Strlen30(zFilename) + 1;
@@ -4305,25 +4322,6 @@ sqlite3_int64 sqlite3_uri_int64(
}
/*
-** The Pager stores the Journal filename, WAL filename, and Database filename
-** consecutively in memory, in that order, with prefixes \000\001\000,
-** \002\000, and \003\000, in that order. Thus the three names look like query
-** parameters if you start at the first prefix.
-**
-** This routine backs up a filename to the start of the first prefix.
-**
-** This only works if the filenamed passed in was obtained from the Pager.
-*/
-static const char *startOfNameList(const char *zName){
- while( zName[0]!='\001' || zName[1]!=0 ){
- zName -= 3;
- while( zName[0]!='\000' ){ zName--; }
- zName++;
- }
- return zName-1;
-}
-
-/*
** Translate a filename that was handed to a VFS routine into the corresponding
** database, journal, or WAL file.
**
@@ -4334,14 +4332,26 @@ static const char *startOfNameList(const char *zName){
** corruption.
*/
const char *sqlite3_filename_database(const char *zFilename){
+ return databaseName(zFilename);
return sqlite3_uri_parameter(zFilename - 3, "\003");
}
const char *sqlite3_filename_journal(const char *zFilename){
- const char *z = sqlite3_uri_parameter(startOfNameList(zFilename), "\001");
- return ALWAYS(z) && z[0] ? z : 0;
+ zFilename = databaseName(zFilename);
+ zFilename += sqlite3Strlen30(zFilename) + 1;
+ while( zFilename[0] ){
+ zFilename += sqlite3Strlen30(zFilename) + 1;
+ zFilename += sqlite3Strlen30(zFilename) + 1;
+ }
+ return zFilename + 1;
}
const char *sqlite3_filename_wal(const char *zFilename){
- return sqlite3_uri_parameter(startOfNameList(zFilename), "\002");
+#ifdef SQLITE_OMIT_WAL
+ return 0;
+#else
+ zFilename = sqlite3_filename_journal(zFilename);
+ zFilename += sqlite3Strlen30(zFilename) + 1;
+ return zFilename;
+#endif
}
/*