Fix #189 unit test "Column.basis" failing on Visual Studio 2013

The implicit cast to std::string() would fallback to const char* with MSVC 2010-2013 (witch does not work with the NULL char in the middle)

Without it, trying to access a binary blob with implicit cast to string
ends up converting it to a C-style char*, damaging the data by truncating it to the first null character!
This commit is contained in:
Sébastien Rombauts 2019-03-03 00:37:44 +01:00
parent ca45c67884
commit 2e69a81ccf
3 changed files with 12 additions and 6 deletions

View File

@ -23,10 +23,6 @@ environment:
- arch: Win32
- arch: Win64
matrix:
allow_failures:
- image: Visual Studio 2013
init:
- echo %APPVEYOR_BUILD_WORKER_IMAGE% - %configuration% - %arch%
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" (set vs=Visual Studio 15 2017)

View File

@ -224,12 +224,16 @@ public:
return getBlob();
}
#if !(defined(_MSC_VER) && _MSC_VER < 1900)
#if !defined(_MSC_VER) || _MSC_VER >= 1900
// NOTE : the following is required by GCC and Clang to cast a Column result in a std::string
// (error: conversion from SQLite::Column to non-scalar type std::string {aka std::basic_string<char>})
// and also required for Microsoft Visual Studio 2015 and newer
// but is not working under Microsoft Visual Studio 2010, 2012 and 2013
// (error C2440: 'initializing' : cannot convert from 'SQLite::Column' to 'std::basic_string<_Elem,_Traits,_Ax>'
// [...] constructor overload resolution was ambiguous)
// WARNING: without it, trying to access a binary blob with implicit cast to string
// ends up converting it to a C-style char*, damaging the data by truncating it to the first null character!
// (see https://github.com/SRombauts/SQLiteCpp/issues/189 Visual Studio 2013: unit test "Column.basis" failing)
/**
* @brief Inline cast operator to std::string
*

View File

@ -68,7 +68,11 @@ TEST(Column, basis) {
const int integer = query.getColumn(2); // operator int()
const double real = query.getColumn(3); // operator double()
const void* pblob = query.getColumn(4); // operator void*()
const std::string sblob = query.getColumn(4); // operator std::string() (or const char* with MSVC)
#if !defined(_MSC_VER) || _MSC_VER >= 1900
// This implicit cast should use operator std::string()
// but would fallback to const char* with MSVC 2010-2013 (witch does not work with the NULL char in the middle)
const std::string sblob = query.getColumn(4); // operator std::string()
#endif
const void* pempty = query.getColumn(5); // operator void*()
EXPECT_EQ(1, id1);
EXPECT_EQ(1, id2);
@ -81,8 +85,10 @@ TEST(Column, basis) {
EXPECT_EQ(-123, integer);
EXPECT_EQ(0.123, real);
EXPECT_EQ(0, memcmp("bl\0b", pblob, size));
#if !defined(_MSC_VER) || _MSC_VER >= 1900
EXPECT_EQ((size_t)size, sblob.size());
EXPECT_EQ(0, memcmp("bl\0b", &sblob[0], size));
#endif
EXPECT_EQ(NULL, pempty);
}