diff options
author | drh <drh@noemail.net> | 2020-01-27 14:40:44 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2020-01-27 14:40:44 +0000 |
commit | 532b0d23fd80082a8706ec683b1c7afed26ee6c4 (patch) | |
tree | 0bb03e9102158f00f5409e974a250b3ac5d74283 /src/main.c | |
parent | 9a3bdeba3e87de596e0a97ac84319183d6fc557f (diff) | |
download | sqlite-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.c | 54 |
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 } /* |