Skip to content

Commit a0f96c1

Browse files
authored
Merge pull request #201 from marciso/dev
fix sequence points between getting text and its length
2 parents 2bc80c7 + b66ef0a commit a0f96c1

File tree

2 files changed

+34
-19
lines changed

2 files changed

+34
-19
lines changed

CMakeLists.txt

+6-6
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@ enable_testing()
3535
add_library (sqlite_modern_cpp INTERFACE)
3636
target_include_directories(sqlite_modern_cpp INTERFACE hdr/)
3737

38-
add_executable(tests ${TEST_SOURCES})
39-
target_include_directories(tests INTERFACE ${SQLITE3_INCLUDE_DIRS})
38+
add_executable(tests_runner ${TEST_SOURCES})
39+
target_include_directories(tests_runner INTERFACE ${SQLITE3_INCLUDE_DIRS})
4040
if(ENABLE_SQLCIPHER_TESTS)
41-
target_link_libraries(tests Catch2::Catch2 sqlite_modern_cpp sqlite3::sqlite3 -lsqlcipher)
41+
target_link_libraries(tests_runner Catch2::Catch2 sqlite_modern_cpp sqlite3::sqlite3 -lsqlcipher)
4242
else()
43-
target_link_libraries(tests Catch2::Catch2 sqlite_modern_cpp sqlite3::sqlite3)
43+
target_link_libraries(tests_runner Catch2::Catch2 sqlite_modern_cpp sqlite3::sqlite3)
4444
endif()
4545

46-
catch_discover_tests(tests)
47-
target_compile_options(tests PUBLIC $<$<CXX_COMPILER_ID:MSVC>:/Zc:__cplusplus> )
46+
catch_discover_tests(tests_runner)
47+
target_compile_options(tests_runner PUBLIC $<$<CXX_COMPILER_ID:MSVC>:/Zc:__cplusplus> )
4848

4949
# Place the file in the source directory, permitting us to place a single configuration file for YCM there.
5050
# YCM is the code-completion engine for (neo)vim https://github.com/Valloric/YouCompleteMe

hdr/sqlite_modern_cpp/type_wrapper.h

+28-13
Original file line numberDiff line numberDiff line change
@@ -193,17 +193,25 @@ namespace sqlite {
193193
}
194194

195195
// Convert char* to string_view to trigger op<<(..., const str_ref )
196-
template<std::size_t N> inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const char(&STR)[N]) {
197-
return sqlite3_bind_text(stmt, inx, &STR[0], N-1, SQLITE_TRANSIENT);
196+
template<std::size_t N> inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const char(&STR)[N]) {
197+
return sqlite3_bind_text(stmt, inx, &STR[0], N-1, SQLITE_TRANSIENT);
198198
}
199199

200200
inline std::string get_col_from_db(sqlite3_stmt* stmt, int inx, result_type<std::string>) {
201-
return sqlite3_column_type(stmt, inx) == SQLITE_NULL ? std::string() :
202-
std::string(reinterpret_cast<char const *>(sqlite3_column_text(stmt, inx)), sqlite3_column_bytes(stmt, inx));
201+
if ( sqlite3_column_type(stmt, inx) == SQLITE_NULL ) {
202+
return std::string();
203+
}
204+
char const * ptr = reinterpret_cast<char const *>(sqlite3_column_text(stmt, inx));
205+
// call sqlite3_column_text explicitely before sqlite3_column_bytes: it may convert the value to text
206+
return std::string(ptr, sqlite3_column_bytes(stmt, inx));
203207
}
204-
inline std::string get_val_from_db(sqlite3_value *value, result_type<std::string >) {
205-
return sqlite3_value_type(value) == SQLITE_NULL ? std::string() :
206-
std::string(reinterpret_cast<char const *>(sqlite3_value_text(value)), sqlite3_value_bytes(value));
208+
inline std::string get_val_from_db(sqlite3_value *value, result_type<std::string>) {
209+
if ( sqlite3_value_type(value) == SQLITE_NULL ) {
210+
return std::string();
211+
}
212+
char const * ptr = reinterpret_cast<char const *>(sqlite3_value_text(value));
213+
// call sqlite3_column_text explicitely before sqlite3_column_bytes: it may convert the value to text
214+
return std::string(ptr, sqlite3_value_bytes(value));
207215
}
208216

209217
inline void store_result_in_db(sqlite3_context* db, str_ref val) {
@@ -222,12 +230,19 @@ namespace sqlite {
222230
}
223231

224232
inline std::u16string get_col_from_db(sqlite3_stmt* stmt, int inx, result_type<std::u16string>) {
225-
return sqlite3_column_type(stmt, inx) == SQLITE_NULL ? std::u16string() :
226-
std::u16string(reinterpret_cast<char16_t const *>(sqlite3_column_text16(stmt, inx)), sqlite3_column_bytes16(stmt, inx));
233+
if ( sqlite3_column_type(stmt, inx) == SQLITE_NULL ) {
234+
return std::u16string();
235+
}
236+
char16_t const * ptr = reinterpret_cast<char16_t const *>(sqlite3_column_text16(stmt, inx));
237+
// call sqlite3_column_text16 explicitely before sqlite3_column_bytes16: it may convert the value to text
238+
return std::u16string(ptr, sqlite3_column_bytes16(stmt, inx));
227239
}
228240
inline std::u16string get_val_from_db(sqlite3_value *value, result_type<std::u16string>) {
229-
return sqlite3_value_type(value) == SQLITE_NULL ? std::u16string() :
230-
std::u16string(reinterpret_cast<char16_t const *>(sqlite3_value_text16(value)), sqlite3_value_bytes16(value));
241+
if ( sqlite3_value_type(value) == SQLITE_NULL ) {
242+
return std::u16string();
243+
}
244+
char16_t const * ptr = reinterpret_cast<char16_t const *>(sqlite3_value_text16(value));
245+
return std::u16string(ptr, sqlite3_value_bytes16(value));
231246
}
232247

233248
inline void store_result_in_db(sqlite3_context* db, u16str_ref val) {
@@ -273,16 +288,16 @@ namespace sqlite {
273288
if(sqlite3_column_type(stmt, inx) == SQLITE_NULL) {
274289
return {};
275290
}
276-
int bytes = sqlite3_column_bytes(stmt, inx);
277291
T const* buf = reinterpret_cast<T const *>(sqlite3_column_blob(stmt, inx));
292+
int bytes = sqlite3_column_bytes(stmt, inx);
278293
return std::vector<T, A>(buf, buf + bytes/sizeof(T));
279294
}
280295
template<typename T, typename A> inline std::vector<T, A> get_val_from_db(sqlite3_value *value, result_type<std::vector<T, A>>) {
281296
if(sqlite3_value_type(value) == SQLITE_NULL) {
282297
return {};
283298
}
284-
int bytes = sqlite3_value_bytes(value);
285299
T const* buf = reinterpret_cast<T const *>(sqlite3_value_blob(value));
300+
int bytes = sqlite3_value_bytes(value);
286301
return std::vector<T, A>(buf, buf + bytes/sizeof(T));
287302
}
288303

0 commit comments

Comments
 (0)