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:
@ -133,9 +133,11 @@ void DatabaseProtobufAdapter::TypeBridge_string::bind(MYSQL_BIND *bind, const go
|
|||||||
/* Handle the NULL case */
|
/* Handle the NULL case */
|
||||||
if (insert_null(bind, msg)) return;
|
if (insert_null(bind, msg)) return;
|
||||||
|
|
||||||
|
buffer = ref->GetString(*msg, desc);
|
||||||
|
|
||||||
bind->buffer_type = MYSQL_TYPE_STRING;
|
bind->buffer_type = MYSQL_TYPE_STRING;
|
||||||
bind->buffer = (void *) ref->GetString(*msg, desc).c_str();
|
bind->buffer = (void *) buffer.c_str();
|
||||||
bind->buffer_length = ref->GetString(*msg, desc).length();
|
bind->buffer_length = buffer.length();
|
||||||
}
|
}
|
||||||
void DatabaseProtobufAdapter::TypeBridge_enum::bind(MYSQL_BIND *bind, const google::protobuf::Message *msg) {
|
void DatabaseProtobufAdapter::TypeBridge_enum::bind(MYSQL_BIND *bind, const google::protobuf::Message *msg) {
|
||||||
const google::protobuf::Reflection *ref = msg->GetReflection();
|
const google::protobuf::Reflection *ref = msg->GetReflection();
|
||||||
|
|||||||
@ -138,6 +138,7 @@ class DatabaseProtobufAdapter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TypeBridge_string : TypeBridge {
|
struct TypeBridge_string : TypeBridge {
|
||||||
|
std::string buffer;
|
||||||
TypeBridge_string(const google::protobuf::FieldDescriptor *desc)
|
TypeBridge_string(const google::protobuf::FieldDescriptor *desc)
|
||||||
: TypeBridge(desc){};
|
: TypeBridge(desc){};
|
||||||
virtual std::string sql_type() { return "TEXT"; };
|
virtual std::string sql_type() { return "TEXT"; };
|
||||||
|
|||||||
Reference in New Issue
Block a user