Fixed GH #1155: Select from MySQL table with longtext column causes SIGSEGV (#1164)

This commit is contained in:
jnytra
2017-07-06 00:44:21 +02:00
committed by Aleksandar Fabijanic
parent 15c076b3ea
commit f8bacb47b5
6 changed files with 96 additions and 2 deletions

View File

@@ -132,6 +132,16 @@ bool Extractor::extract(std::size_t pos, std::string& val)
MetaColumn::ColumnDataType columnType = _metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type();
if (columnType != Poco::Data::MetaColumn::FDT_STRING && columnType != Poco::Data::MetaColumn::FDT_BLOB)
throw MySQLException("Extractor: not a string");
if (columnType == Poco::Data::MetaColumn::FDT_BLOB && _metadata.length(pos) > 0 && _metadata.rawData(pos) == NULL)
{
std::vector<char> buffer(_metadata.length(pos), 0);
bool ret = realExtractFixedBlob(pos, _metadata.row()[pos].buffer_type, buffer.data(), buffer.size());
if (ret)
val.assign(buffer.data(), buffer.size());
return ret;
}
val.assign(reinterpret_cast<const char*>(_metadata.rawData(pos)), _metadata.length(pos));
return true;
@@ -146,8 +156,19 @@ bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
if (_metadata.isNull(static_cast<Poco::UInt32>(pos)))
return false;
if (_metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type() != Poco::Data::MetaColumn::FDT_BLOB)
MetaColumn::ColumnDataType columnType = _metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type();
if (columnType != Poco::Data::MetaColumn::FDT_BLOB)
throw MySQLException("Extractor: not a blob");
if (columnType == Poco::Data::MetaColumn::FDT_BLOB && _metadata.length(pos) > 0 && _metadata.rawData(pos) == NULL)
{
std::vector<unsigned char> buffer(_metadata.length(pos), 0);
bool ret = realExtractFixedBlob(pos, _metadata.row()[pos].buffer_type, buffer.data(), buffer.size());
if (ret)
val.assignRaw(buffer.data(), buffer.size());
return ret;
}
val.assignRaw(_metadata.rawData(pos), _metadata.length(pos));
return true;
@@ -162,9 +183,20 @@ bool Extractor::extract(std::size_t pos, Poco::Data::CLOB& val)
if (_metadata.isNull(static_cast<Poco::UInt32>(pos)))
return false;
if (_metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type() != Poco::Data::MetaColumn::FDT_BLOB)
MetaColumn::ColumnDataType columnType = _metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type();
if (columnType != Poco::Data::MetaColumn::FDT_BLOB)
throw MySQLException("Extractor: not a blob");
if (columnType == Poco::Data::MetaColumn::FDT_BLOB && _metadata.length(pos) > 0 && _metadata.rawData(pos) == NULL)
{
std::vector<char> buffer(_metadata.length(pos), 0);
bool ret = realExtractFixedBlob(pos, _metadata.row()[pos].buffer_type, buffer.data(), buffer.size());
if (ret)
val.assignRaw(buffer.data(), buffer.size());
return ret;
}
val.assignRaw(reinterpret_cast<const char*>(_metadata.rawData(pos)), _metadata.length(pos));
return true;
}
@@ -253,6 +285,21 @@ bool Extractor::realExtractFixed(std::size_t pos, enum_field_types type, void* b
return isNull == 0;
}
bool Extractor::realExtractFixedBlob(std::size_t pos, enum_field_types type, void* buffer, size_t len)
{
MYSQL_BIND bind = {0};
my_bool isNull = 0;
bind.is_null = &isNull;
bind.buffer_type = type;
bind.buffer = buffer;
bind.buffer_length = len;
if (!_stmt.fetchColumn(pos, &bind))
return false;
return isNull == 0;
}
//////////////
// Not implemented