Skip to content

Commit 3383a31

Browse files
author
Marcin Sobieszczanski
committed
fix sequence points between sqlite3_column_{blob,text{,16}} and sqlite3_value_bytes{,16}
1 parent 65b82cf commit 3383a31

File tree

1 file changed

+28
-13
lines changed

1 file changed

+28
-13
lines changed

hdr/sqlite_modern_cpp/type_wrapper.h

Lines changed: 28 additions & 13 deletions
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)