From c07eebd82a85e57b771f8a39c8927d1c3c820a40 Mon Sep 17 00:00:00 2001 From: hvlad Date: Fri, 16 Apr 2010 10:37:26 +0000 Subject: [PATCH] Fixed bug CORE-2969 : rdb$set_context does NOT allow to overwrite any vars after encountering limit (default=1000) of them. --- src/common/classes/GenericMap.h | 9 ++++++ src/jrd/functions.cpp | 54 ++++++++++++++++++--------------- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/common/classes/GenericMap.h b/src/common/classes/GenericMap.h index f585022245..34206afdc9 100644 --- a/src/common/classes/GenericMap.h +++ b/src/common/classes/GenericMap.h @@ -162,6 +162,15 @@ public: return false; } + // Returns pointer to the found value or null otherwise + ValueType* get(const KeyType& key) { + if (tree.locate(key)) { + return &tree.current()->second; + } + + return NULL; + } + bool getFirst() { return tree.getFirst(); } bool getLast() { return tree.getLast(); } diff --git a/src/jrd/functions.cpp b/src/jrd/functions.cpp index 0ac1abbfd2..ccb34466b9 100644 --- a/src/jrd/functions.cpp +++ b/src/jrd/functions.cpp @@ -311,52 +311,58 @@ static SLONG set_context(const vary* ns_vary, const vary* name_vary, const vary* const Firebird::string ns_str(ns_vary->vary_string, ns_vary->vary_length); const Firebird::string name_str(name_vary->vary_string, name_vary->vary_length); + Firebird::StringMap* context_vars = NULL; + bool result = false; + if (ns_str == USER_SESSION_NAMESPACE) { Attachment* att = tdbb->getAttachment(); - if (!att) { fb_assert(false); return 0; } - if (!value_vary) - return att->att_context_vars.remove(name_str); - - if (att->att_context_vars.count() >= MAX_CONTEXT_VARS) { - // "Too many context variables" - ERR_post(isc_ctx_too_big, isc_arg_end); - } - - return att->att_context_vars.put(name_str, - Firebird::string(value_vary->vary_string, value_vary->vary_length)); + context_vars = &att->att_context_vars; } - else if (ns_str == USER_TRANSACTION_NAMESPACE) { + else if (ns_str == USER_TRANSACTION_NAMESPACE) + { jrd_tra* tra = tdbb->getTransaction(); - if (!tra) { fb_assert(false); return 0; } - if (!value_vary) - return tra->tra_context_vars.remove(name_str); - - if (tra->tra_context_vars.count() >= MAX_CONTEXT_VARS) { - // "Too many context variables" - ERR_post(isc_ctx_too_big, isc_arg_end); - } - - return tra->tra_context_vars.put(name_str, - Firebird::string(value_vary->vary_string, value_vary->vary_length)); + context_vars = &tra->tra_context_vars; } - else { + else + { // "Invalid namespace name %s passed to %s" ERR_post(isc_ctx_namespace_invalid, isc_arg_string, ERR_cstring(ns_str.c_str()), isc_arg_string, RDB_SET_CONTEXT, isc_arg_end); return 0; } + + if (!value_vary) { + result = context_vars->remove(name_str); + } + else if (context_vars->count() == MAX_CONTEXT_VARS) + { + Firebird::string *rc = context_vars->get(name_str); + if (rc) + { + rc->assign(value_vary->vary_string, value_vary->vary_length); + result = true; + } + else + ERR_post(isc_ctx_too_big, isc_arg_end); // "Too many context variables" + } + else + { + result = context_vars->put(name_str, Firebird::string(value_vary->vary_string, value_vary->vary_length)); + } + + return (SLONG) result; } static int test(const long* n, char *result)