From 5f014440eef11d0020d6d534c9926451c336ff50 Mon Sep 17 00:00:00 2001 From: ailiujiarui <115072567+ailiujiarui@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:46:55 +0800 Subject: [PATCH] feat: fix memory leak in Enforce() (#246) --- include/casbin/model/exprtk_config.h | 39 +++++++++++++++++++++------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/include/casbin/model/exprtk_config.h b/include/casbin/model/exprtk_config.h index 110cee33..4b5167d4 100644 --- a/include/casbin/model/exprtk_config.h +++ b/include/casbin/model/exprtk_config.h @@ -245,44 +245,65 @@ class ExprtkFunctionFactory { public: static std::shared_ptr GetExprtkFunction(ExprtkFunctionType type, int narg, std::shared_ptr rm = nullptr) { std::string idenfier(narg, 'S'); + + // Static map to act as an object pool + static std::unordered_map> pool; + + // Create a key for the object pool using the type and identifier + std::string key = std::to_string(static_cast(type)) + idenfier; + + // Check if the object already exists in the pool + if (pool.find(key) != pool.end()) { + // If it exists, return the existing object + return pool[key]; + } + + // If it doesn't exist, create a new object std::shared_ptr func = nullptr; switch (type) { case ExprtkFunctionType::Gfunction: func = std::make_shared(idenfier, rm); break; case ExprtkFunctionType::KeyMatch: - func.reset(new ExprtkMatchFunction(idenfier, KeyMatch)); + func = std::make_shared(idenfier, KeyMatch); break; case ExprtkFunctionType::KeyMatch2: - func.reset(new ExprtkMatchFunction(idenfier, KeyMatch2)); + func = std::make_shared(idenfier, KeyMatch2); break; case ExprtkFunctionType::KeyMatch3: - func.reset(new ExprtkMatchFunction(idenfier, KeyMatch3)); + func = std::make_shared(idenfier, KeyMatch3); break; case ExprtkFunctionType::KeyMatch4: - func.reset(new ExprtkMatchFunction(idenfier, KeyMatch4)); + func = std::make_shared(idenfier, KeyMatch4); break; case ExprtkFunctionType::IpMatch: - func.reset(new ExprtkMatchFunction(idenfier, IPMatch)); + func = std::make_shared(idenfier, IPMatch); break; case ExprtkFunctionType::RegexMatch: - func.reset(new ExprtkMatchFunction(idenfier, RegexMatch)); + func = std::make_shared(idenfier, RegexMatch); break; case ExprtkFunctionType::KeyGet: - func.reset(new ExprtkGetFunction(idenfier, KeyGet)); + func = std::make_shared(idenfier, KeyGet); break; case ExprtkFunctionType::KeyGet2: - func.reset(new ExprtkGetWithPathFunction(idenfier, KeyGet2)); + func = std::make_shared(idenfier, KeyGet2); break; case ExprtkFunctionType::KeyGet3: - func.reset(new ExprtkGetWithPathFunction(idenfier, KeyGet3)); + func = std::make_shared(idenfier, KeyGet3); break; default: func = nullptr; } + // If a new object was created, add it to the pool + if (func) { + pool[key] = func; + } + pool.clear(); + // Return the newly created or existing object return func; } + }; } // namespace casbin