From d962a322ea9e641b8891b771452b22f929c893bf Mon Sep 17 00:00:00 2001 From: Horst Schirmeier Date: Thu, 18 Sep 2014 19:10:16 +0200 Subject: [PATCH] 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 --- src/core/util/DatabaseProtobufAdapter.cc | 6 ++++-- src/core/util/DatabaseProtobufAdapter.hpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/util/DatabaseProtobufAdapter.cc b/src/core/util/DatabaseProtobufAdapter.cc index cd7cf0f7..6c4a0c29 100644 --- a/src/core/util/DatabaseProtobufAdapter.cc +++ b/src/core/util/DatabaseProtobufAdapter.cc @@ -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(); diff --git a/src/core/util/DatabaseProtobufAdapter.hpp b/src/core/util/DatabaseProtobufAdapter.hpp index 6f0f8ad1..6c8e5cf9 100644 --- a/src/core/util/DatabaseProtobufAdapter.hpp +++ b/src/core/util/DatabaseProtobufAdapter.hpp @@ -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"; };