From b18fe3ddd0af8cd74b53589d4f1a7c9855eb3ad8 Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Wed, 5 Jun 2019 20:26:50 -0400 Subject: [PATCH] horrific memeory leak in rate limiter --- extensions/bingtranslate.cpp | 2 +- extensions/googletranslate.cpp | 2 +- extensions/network.h | 23 ++++++++++++++++++++++- extensions/util.h | 12 ------------ 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/extensions/bingtranslate.cpp b/extensions/bingtranslate.cpp index 082b8a7..02515b6 100644 --- a/extensions/bingtranslate.cpp +++ b/extensions/bingtranslate.cpp @@ -113,7 +113,7 @@ std::wstring Translate(const std::wstring& text, std::wstring translateFrom, std // Response formatted as JSON: translation starts with :" and ends with "} else if (std::wsmatch results; std::regex_search(response.value(), results, std::wregex(L":\"(.+)\"\\}"))) translation = results[1]; - Escape(translation); + Unescape(translation); return translation; } diff --git a/extensions/googletranslate.cpp b/extensions/googletranslate.cpp index b4051c5..3906fcb 100644 --- a/extensions/googletranslate.cpp +++ b/extensions/googletranslate.cpp @@ -159,7 +159,7 @@ bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo) { for (std::wsmatch results; std::regex_search(response.value(), results, std::wregex(L"\\[\"(.*?)\",[n\"]")); response = results.suffix()) translation += std::wstring(results[1]) + L" "; - Escape(translation); + Unescape(translation); } else { diff --git a/extensions/network.h b/extensions/network.h index d47b53f..2d7026a 100644 --- a/extensions/network.h +++ b/extensions/network.h @@ -24,7 +24,7 @@ inline std::optional ReceiveHttpRequest(HINTERNET request) return StringToWideString(data); } -inline void Escape(std::wstring& text) +inline void Unescape(std::wstring& text) { for (int i = 0; i < text.size(); ++i) { @@ -37,3 +37,24 @@ inline void Escape(std::wstring& text) } } } + + +class RateLimiter +{ +public: + RateLimiter(int tokenCount, int delay) : tokenCount(tokenCount), delay(delay) {} + + bool Request() + { + auto tokens = this->tokens.Acquire(); + tokens->push_back(GetTickCount()); + if (tokens->size() > tokenCount * 5) tokens->erase(tokens->begin(), tokens->begin() + tokenCount * 3); + tokens->erase(std::remove_if(tokens->begin(), tokens->end(), [this](DWORD token) { return GetTickCount() - token > delay; }), tokens->end()); + return tokens->size() < tokenCount; + } + + const int tokenCount, delay; + +private: + Synchronized> tokens; +}; diff --git a/extensions/util.h b/extensions/util.h index c362d71..3291367 100644 --- a/extensions/util.h +++ b/extensions/util.h @@ -2,18 +2,6 @@ #include "common.h" -class RateLimiter -{ -public: - RateLimiter(int requests, int delay) : requestsLeft(requests), delay(delay) {} - bool Request() { CreateTimerQueueTimer(DUMMY, timerQueue, [](void* This, BOOLEAN) { ((RateLimiter*)This)->requestsLeft += 1; }, this, delay, 0, 0); return --requestsLeft > 0; } - int delay; - -private: - std::atomic requestsLeft; - AutoHandle> timerQueue = CreateTimerQueue(); -}; - inline std::wstring StringToWideString(const std::string& text) { std::vector buffer(text.size() + 1);