DatabaseProtobufAdapter: fix string insertion

This change fixes the Protobuf->MySQL bridge for strings, which were
corrupted in rare cases, especially with debug builds of the
DatabaseCampaign.  String columns in result tables from any campaign
up to this point may contain corrupted data.

The core reason for the corruption was that the TypeBridge_string
bound a temporary (a nameless local variable) to the prepared
statement.  This temporary is destroyed before the subsequent call to
mysql_stmt_bind_param(), and the string within can only be referenced
successfully if it has not been overwritten yet.  The solution is to
copy the string to a bridge-internal variable.

Although it might seem that TypeBridge_enum has the same problem, the
protobuf library seems to return references to internal string
constants when retrieving the enum values.

Change-Id: Id127e6b3333d7c304d688e45de9bea44bbc610b0
This commit is contained in:
Horst Schirmeier
2014-09-18 19:10:16 +02:00
parent db2a0dc056
commit d962a322ea
2 changed files with 5 additions and 2 deletions

View File

@ -133,9 +133,11 @@ void DatabaseProtobufAdapter::TypeBridge_string::bind(MYSQL_BIND *bind, const go
/* Handle the NULL case */
if (insert_null(bind, msg)) return;
buffer = ref->GetString(*msg, desc);
bind->buffer_type = MYSQL_TYPE_STRING;
bind->buffer = (void *) ref->GetString(*msg, desc).c_str();
bind->buffer_length = ref->GetString(*msg, desc).length();
bind->buffer = (void *) buffer.c_str();
bind->buffer_length = buffer.length();
}
void DatabaseProtobufAdapter::TypeBridge_enum::bind(MYSQL_BIND *bind, const google::protobuf::Message *msg) {
const google::protobuf::Reflection *ref = msg->GetReflection();

View File

@ -138,6 +138,7 @@ class DatabaseProtobufAdapter {
};
struct TypeBridge_string : TypeBridge {
std::string buffer;
TypeBridge_string(const google::protobuf::FieldDescriptor *desc)
: TypeBridge(desc){};
virtual std::string sql_type() { return "TEXT"; };