Skip to content

Commit

Permalink
Merge pull request #392 from haileys/resultset-close-memory-leak
Browse files Browse the repository at this point in the history
Always call sqlite3_finalize in deallocate func
  • Loading branch information
flavorjones authored Jan 3, 2024
2 parents 0d487ae + 0c24631 commit 5c53ad8
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
14 changes: 13 additions & 1 deletion ext/sqlite3/statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@

VALUE cSqlite3Statement;

static void
statement_deallocate(void *data)
{
sqlite3StmtRubyPtr s = (sqlite3StmtRubyPtr)data;

if (s->st) {
sqlite3_finalize(s->st);
}

xfree(data);
}

static size_t
statement_memsize(const void *data)
{
Expand All @@ -18,7 +30,7 @@ static const rb_data_type_t statement_type = {
"SQLite3::Backup",
{
NULL,
RUBY_TYPED_DEFAULT_FREE,
statement_deallocate,
statement_memsize,
},
0,
Expand Down
1 change: 1 addition & 0 deletions sqlite3.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ Gem::Specification.new do |s|
"test/test_integration_resultset.rb",
"test/test_integration_statement.rb",
"test/test_pragmas.rb",
"test/test_resource_cleanup.rb",
"test/test_result_set.rb",
"test/test_sqlite3.rb",
"test/test_statement.rb",
Expand Down
27 changes: 27 additions & 0 deletions test/test_resource_cleanup.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require "helper"

module SQLite3
# these tests will cause ruby_memcheck to report a leak if we're not cleaning up resources
class TestResourceCleanup < SQLite3::TestCase
def test_cleanup_unclosed_database_object
100.times do
SQLite3::Database.new(':memory:')
end
end

def test_cleanup_unclosed_statement_object
100.times do
db = SQLite3::Database.new(':memory:')
db.execute('create table foo(text BLOB)')
db.prepare('select * from foo')
end
end

# def test_cleanup_unclosed_resultset_object
# db = SQLite3::Database.new(':memory:')
# db.execute('create table foo(text BLOB)')
# stmt = db.prepare('select * from foo')
# stmt.execute
# end
end
end

0 comments on commit 5c53ad8

Please sign in to comment.