SOCI / soci

Official repository of the SOCI - The C++ Database Access Library
http://soci.sourceforge.net/
Boost Software License 1.0
1.37k stars 472 forks source link

Using `row::move_as` while iterating `rowset` yields segmentation fault #1144

Open Krzmbrzl opened 2 months ago

Krzmbrzl commented 2 months ago

Originally reported by @avpalienko in https://github.com/SOCI/soci/issues/1141#issuecomment-2057755837

When applying the following patch to the common-tests.h file, the move_as test case will crash due to a segmentation fault:

diff --git a/tests/common-tests.h b/tests/common-tests.h
index d2b8fb42..ffc80fc6 100644
--- a/tests/common-tests.h
+++ b/tests/common-tests.h
@@ -6779,7 +6779,7 @@ TEST_CASE_METHOD(common_tests, "BLOB", "[core][blob]")
         }
         SECTION("move_as")
         {
-            soci::rowset< soci::row > rowSet = (sql.prepare << "select b from soci_test where id=:id", soci::use(id));
+            soci::rowset< soci::row > rowSet = (sql.prepare << "select b from soci_test where id=:id union all select b from soci_test where id=:id", soci::use(id, "id"));
             bool containedData = false;
             for (auto it = rowSet.begin(); it != rowSet.end(); ++it)
             {

The issue was originally reported to happen with Oracle, but I was also able to reproduce it with SQLite3, indicating that the issue is not backend-specific.

Krzmbrzl commented 2 months ago

The problem seems to boil down to this:

Therefore, the fix for this issue would be to find a way to let the row object know about invalidated holders, which should cause it to reinitialize them before trying to use them for data binding.

avpalienko commented 2 months ago

May be we could use shared_ptr inside the "row" class and eliminate move_as altogether ?

Krzmbrzl commented 2 months ago

Nah, the get function cant return a pointer. That'd be inconsistent. Besides, this wouldn't really solve the underlying problem. If the user moves from the dereferenced pointer, we're back at square one with the row object being broken.