In 3.31.1, attempting to access URI Parameters via the sqlite3_uri_* functions 
inside a VFS xFullPathname function returns junk.  This was not an issue in 
3.30.1 or 3.31.0.

The internals of those functions use the new databaseName() function, which 
attempts to find the database name from the path passed info sqlite3_open_v2(). 
 According to the function documentation:

        > This only works if the filename passed in was obtained from the Pager.

However, the xFullPathname function is called before the Pager has opened the 
file, the parameter passed to sqlite3_uri_* functions aren't prefixed by the 4 
null bytes, thus the databaseName() call steps backward too far.

Minimal reproducer:

----------

#include <iostream>
#include <sqlite3.h>

int test_full_path_name(sqlite3_vfs* vfs, const char* zName, int nOut, char* 
zOut)
{
  auto test_param = sqlite3_uri_parameter(zName, "test_param");
  if (!test_param)
  {
    return SQLITE_ERROR;
  }

  return SQLITE_OK;
}

int main()
{
  static sqlite3_vfs uzip_vfs = {
      3,
      0,
      sqlite3_vfs_find(nullptr)->mxPathname,
      nullptr,
      "test-vfs",
      nullptr,
      sqlite3_vfs_find(nullptr)->xOpen,
      sqlite3_vfs_find(nullptr)->xDelete,
      sqlite3_vfs_find(nullptr)->xAccess,
      test_full_path_name,
      sqlite3_vfs_find(nullptr)->xDlOpen,
      sqlite3_vfs_find(nullptr)->xDlError,
      sqlite3_vfs_find(nullptr)->xDlSym,
      sqlite3_vfs_find(nullptr)->xDlClose,
      sqlite3_vfs_find(nullptr)->xRandomness,
      sqlite3_vfs_find(nullptr)->xSleep,
      sqlite3_vfs_find(nullptr)->xCurrentTime,
      sqlite3_vfs_find(nullptr)->xGetLastError,
      sqlite3_vfs_find(nullptr)->xCurrentTimeInt64,
      sqlite3_vfs_find(nullptr)->xSetSystemCall,
      sqlite3_vfs_find(nullptr)->xGetSystemCall,
      sqlite3_vfs_find(nullptr)->xNextSystemCall};

  int rc = sqlite3_vfs_register(&uzip_vfs, 0);
  if (rc != SQLITE_OK)
  {
    std::cout << "ERROR (" << rc << "): vfs registration failed." << std::endl;
  }

  std::string open_path{"file:E:/Temp/test.sqlite?test_param=hello"};

  sqlite3* db{nullptr};
  rc = sqlite3_open_v2(open_path.c_str(), &db, SQLITE_OPEN_READONLY | 
SQLITE_OPEN_URI, "test-vfs");
  if (rc != SQLITE_OK)
  {
    std::cout << "ERROR (" << rc << "): opening the database failed." << 
std::endl;
  }

  return 0;
}
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to