From 1839dbd165989c710ee6d7e8fc69f2f07da618c5 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 28 Oct 2024 17:02:29 -0400 Subject: [PATCH 1/3] feat: allow URI filenames See https://www.sqlite.org/uri.html --- CHANGELOG.md | 5 +++++ ext/sqlite3/extconf.rb | 3 ++- test/test_database_uri.rb | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 test/test_database_uri.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 88b1d0d4..96cc1162 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## next / unreleased +### Added + +- URI filenames are now allowed. This allows the injection of some behavior via recognized query parameters. See https://www.sqlite.org/uri.html for more information. #571 @flavorjones + + ### Improved - SQL Syntax errors during `Database#prepare` will raise a verbose exception with a multiline message indicating with a "^" exactly where in the statement the error occurred. [#554] @fractaledmind @flavorjones diff --git a/ext/sqlite3/extconf.rb b/ext/sqlite3/extconf.rb index 6c829bdb..b154c9a8 100644 --- a/ext/sqlite3/extconf.rb +++ b/ext/sqlite3/extconf.rb @@ -61,7 +61,8 @@ def configure_packaged_libraries "-fPIC", # needed for linking the static library into a shared library "-O2", # see https://github.com/sparklemotion/sqlite3-ruby/issues/335 for some benchmarks "-fvisibility=hidden", # see https://github.com/rake-compiler/rake-compiler-dock/issues/87 - "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1" + "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1", + "-DSQLITE_USE_URI=1" ] env["CFLAGS"] = [user_cflags, env["CFLAGS"], more_cflags].flatten.join(" ") recipe.configure_options += env.select { |k, v| ENV_ALLOWLIST.include?(k) } diff --git a/test/test_database_uri.rb b/test/test_database_uri.rb new file mode 100644 index 00000000..6c3dfe31 --- /dev/null +++ b/test/test_database_uri.rb @@ -0,0 +1,32 @@ +require "helper" +require "tempfile" +require "pathname" + +module SQLite3 + class TestDatabaseURI < SQLite3::TestCase + def test_open_absolute_file_uri + Tempfile.open "test.db" do |file| + assert SQLite3::Database.new("file:#{file.path}") + end + end + + def test_open_relative_file_uri + Dir.mktmpdir do |dir| + Dir.chdir dir do + assert SQLite3::Database.new("file:test.db") + assert_path_exists "test.db" + end + end + end + + def test_open_file_uri_readonly + Tempfile.open "test.db" do |file| + db = SQLite3::Database.new("file:#{file.path}?mode=ro") + + assert_raise(SQLite3::ReadOnlyException) do + db.execute("CREATE TABLE foos (id integer)") + end + end + end + end +end From fe026b295f0a31d5c20df0c4534357b84ab08cd9 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 29 Oct 2024 14:55:47 -0400 Subject: [PATCH 2/3] test: skil URI tests on windows there are a lot of caveats about them in https://www.sqlite.org/uri.html and I don't have the energy to deal with it today. --- test/helper.rb | 4 ++++ test/test_database_uri.rb | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/test/helper.rb b/test/helper.rb index 9f159247..32ac8dd8 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -21,5 +21,9 @@ def i_am_running_in_valgrind # https://stackoverflow.com/questions/365458/how-can-i-detect-if-a-program-is-running-from-within-valgrind/62364698#62364698 ENV["LD_PRELOAD"] =~ /valgrind|vgpreload/ end + + def windows? + ::RUBY_PLATFORM =~ /mingw|mswin/ + end end end diff --git a/test/test_database_uri.rb b/test/test_database_uri.rb index 6c3dfe31..909c93c5 100644 --- a/test/test_database_uri.rb +++ b/test/test_database_uri.rb @@ -5,27 +5,39 @@ module SQLite3 class TestDatabaseURI < SQLite3::TestCase def test_open_absolute_file_uri + skip("windows uri paths are hard") if windows? + Tempfile.open "test.db" do |file| - assert SQLite3::Database.new("file:#{file.path}") + db = SQLite3::Database.new("file:#{file.path}") + assert db + db.close end end def test_open_relative_file_uri + skip("windows uri paths are hard") if windows? + Dir.mktmpdir do |dir| Dir.chdir dir do - assert SQLite3::Database.new("file:test.db") + db = SQLite3::Database.new("file:test.db") + assert db assert_path_exists "test.db" + db.close end end end def test_open_file_uri_readonly + skip("windows uri paths are hard") if windows? + Tempfile.open "test.db" do |file| db = SQLite3::Database.new("file:#{file.path}?mode=ro") assert_raise(SQLite3::ReadOnlyException) do db.execute("CREATE TABLE foos (id integer)") end + + db.close end end end From 7e750ace9a2482143a4c13fda258448292a98e5b Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 29 Oct 2024 15:20:55 -0400 Subject: [PATCH 3/3] test: skip URI tests for sqlcipher since the compile-time option may not be on --- test/test_database_uri.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_database_uri.rb b/test/test_database_uri.rb index 909c93c5..72beda99 100644 --- a/test/test_database_uri.rb +++ b/test/test_database_uri.rb @@ -6,6 +6,7 @@ module SQLite3 class TestDatabaseURI < SQLite3::TestCase def test_open_absolute_file_uri skip("windows uri paths are hard") if windows? + skip("sqlcipher may not allow URIs") if SQLite3.sqlcipher? Tempfile.open "test.db" do |file| db = SQLite3::Database.new("file:#{file.path}") @@ -16,6 +17,7 @@ def test_open_absolute_file_uri def test_open_relative_file_uri skip("windows uri paths are hard") if windows? + skip("sqlcipher may not allow URIs") if SQLite3.sqlcipher? Dir.mktmpdir do |dir| Dir.chdir dir do @@ -29,6 +31,7 @@ def test_open_relative_file_uri def test_open_file_uri_readonly skip("windows uri paths are hard") if windows? + skip("sqlcipher may not allow URIs") if SQLite3.sqlcipher? Tempfile.open "test.db" do |file| db = SQLite3::Database.new("file:#{file.path}?mode=ro")