diff --git a/mssql_python/pybind/connection/connection.cpp b/mssql_python/pybind/connection/connection.cpp index a22f4c8e..66223b51 100644 --- a/mssql_python/pybind/connection/connection.cpp +++ b/mssql_python/pybind/connection/connection.cpp @@ -188,7 +188,6 @@ SQLRETURN Connection::setAttribute(SQLINTEGER attribute, py::object value) { LOG("Setting SQL attribute"); // SQLPOINTER ptr = nullptr; // SQLINTEGER length = 0; - static std::string buffer; // to hold sensitive data temporarily if (py::isinstance(value)) { // Get the integer value @@ -208,8 +207,6 @@ SQLRETURN Connection::setAttribute(SQLINTEGER attribute, py::object value) { return ret; } else if (py::isinstance(value)) { try { - // Keep buffers alive - static std::vector wstr_buffers; std::string utf8_str = value.cast(); // Convert to wide string @@ -218,24 +215,16 @@ SQLRETURN Connection::setAttribute(SQLINTEGER attribute, py::object value) { LOG("Failed to convert string value to wide string"); return SQL_ERROR; } - - // Limit static buffer growth for memory safety - constexpr size_t MAX_BUFFER_COUNT = 100; - if (wstr_buffers.size() >= MAX_BUFFER_COUNT) { - // Remove oldest 50% of entries when limit reached - wstr_buffers.erase(wstr_buffers.begin(), - wstr_buffers.begin() + (MAX_BUFFER_COUNT / 2)); - } - - wstr_buffers.push_back(wstr); + this->wstrStringBuffer.clear(); + this->wstrStringBuffer = std::move(wstr); SQLPOINTER ptr; SQLINTEGER length; #if defined(__APPLE__) || defined(__linux__) // For macOS/Linux, convert wstring to SQLWCHAR buffer - std::vector sqlwcharBuffer = WStringToSQLWCHAR(wstr); - if (sqlwcharBuffer.empty() && !wstr.empty()) { + std::vector sqlwcharBuffer = WStringToSQLWCHAR(this->wstrStringBuffer); + if (sqlwcharBuffer.empty() && !this->wstrStringBuffer.empty()) { LOG("Failed to convert wide string to SQLWCHAR buffer"); return SQL_ERROR; } @@ -245,9 +234,8 @@ SQLRETURN Connection::setAttribute(SQLINTEGER attribute, py::object value) { sqlwcharBuffer.size() * sizeof(SQLWCHAR)); #else // On Windows, wchar_t and SQLWCHAR are the same size - ptr = const_cast(wstr_buffers.back().c_str()); - length = static_cast( - wstr.length() * sizeof(SQLWCHAR)); + ptr = const_cast(this->wstrStringBuffer.c_str()); + length = static_cast(this->wstrStringBuffer.length() * sizeof(SQLWCHAR)); #endif SQLRETURN ret = SQLSetConnectAttr_ptr(_dbcHandle->get(), @@ -266,21 +254,11 @@ SQLRETURN Connection::setAttribute(SQLINTEGER attribute, py::object value) { } else if (py::isinstance(value) || py::isinstance(value)) { try { - static std::vector buffers; std::string binary_data = value.cast(); - - // Limit static buffer growth - constexpr size_t MAX_BUFFER_COUNT = 100; - if (buffers.size() >= MAX_BUFFER_COUNT) { - // Remove oldest 50% of entries when limit reached - buffers.erase(buffers.begin(), - buffers.begin() + (MAX_BUFFER_COUNT / 2)); - } - - buffers.emplace_back(std::move(binary_data)); - SQLPOINTER ptr = const_cast(buffers.back().c_str()); - SQLINTEGER length = static_cast( - buffers.back().size()); + this->strBytesBuffer.clear(); + this->strBytesBuffer = std::move(binary_data); + SQLPOINTER ptr = const_cast(this->strBytesBuffer.c_str()); + SQLINTEGER length = static_cast(this->strBytesBuffer.size()); SQLRETURN ret = SQLSetConnectAttr_ptr(_dbcHandle->get(), attribute, ptr, length); diff --git a/mssql_python/pybind/connection/connection.h b/mssql_python/pybind/connection/connection.h index 885be39a..37c10340 100644 --- a/mssql_python/pybind/connection/connection.h +++ b/mssql_python/pybind/connection/connection.h @@ -59,6 +59,8 @@ class Connection { bool _autocommit = true; SqlHandlePtr _dbcHandle; std::chrono::steady_clock::time_point _lastUsed; + std::wstring wstrStringBuffer; // wstr buffer for string attribute setting + std::string strBytesBuffer; // string buffer for byte attributes setting }; class ConnectionHandle {