From 8fe1fc4118e33eb98d96fbe3e0bd34aac1d018fe Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Sat, 28 Nov 2020 21:02:01 +0100 Subject: [PATCH] Fix getting redirect URL from curl The char* set by curl_easy_getinfo may not be valid after the next curl_easy_perform, so copy it to a std::string instead. --- include/util.h | 1 + src/util.cpp | 6 ++++++ src/website.cpp | 22 +++++++++------------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/include/util.h b/include/util.h index b3ca774..b1d9007 100644 --- a/include/util.h +++ b/include/util.h @@ -84,6 +84,7 @@ namespace Util std::string getStrippedString(std::string str); std::string makeEtaString(const unsigned long long& iBytesRemaining, const double& dlRate); std::string makeEtaString(const boost::posix_time::time_duration& duration); + std::string CurlHandleGetInfoString(CURL* curlhandle, CURLINFO info); void CurlHandleSetDefaultOptions(CURL* curlhandle, const CurlConfig& conf); CURLcode CurlGetResponse(const std::string& url, std::string& response, int max_retries = -1); CURLcode CurlHandleGetResponse(CURL* curlhandle, std::string& response, int max_retries = -1); diff --git a/src/util.cpp b/src/util.cpp index 9bde950..fefb937 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -756,6 +756,12 @@ void Util::CurlHandleSetDefaultOptions(CURL* curlhandle, const CurlConfig& conf) curl_easy_setopt(curlhandle, CURLOPT_CAINFO, conf.sCACertPath.c_str()); } +std::string Util::CurlHandleGetInfoString(CURL* curlhandle, CURLINFO info) +{ + char* str; + return (curl_easy_getinfo(curlhandle, info, &str) == CURLE_OK) ? str : ""; +} + CURLcode Util::CurlGetResponse(const std::string& url, std::string& response, int max_retries) { CURLcode result; diff --git a/src/website.cpp b/src/website.cpp index bc85639..7fbf0b6 100644 --- a/src/website.cpp +++ b/src/website.cpp @@ -354,12 +354,9 @@ int Website::Login(const std::string& email, const std::string& password) std::cout << curl_easy_strerror(result) << std::endl; } - // Get redirect url - char *redirect_url; - curl_easy_getinfo(curlhandle, CURLINFO_REDIRECT_URL, &redirect_url); - // Handle two step authorization - if (std::string(redirect_url).find("two_step") != std::string::npos) + std::string redirect_url = Util::CurlHandleGetInfoString(curlhandle, CURLINFO_REDIRECT_URL); + if (redirect_url.find("two_step") != std::string::npos) { std::string security_code; std::string tagname_two_step_send = "second_step_authentication[send]"; @@ -370,7 +367,7 @@ int Website::Login(const std::string& email, const std::string& password) std::string tagname_two_step_token; std::string token_two_step; std::string two_step_html = this->getResponse(redirect_url); - redirect_url = NULL; + redirect_url = ""; tree two_step_dom = parser.parseTree(two_step_html); tree::iterator two_step_it = two_step_dom.begin(); @@ -416,26 +413,25 @@ int Website::Login(const std::string& email, const std::string& password) curl_easy_setopt(curlhandle, CURLOPT_FOLLOWLOCATION, 0); result = curl_easy_perform(curlhandle); memory.str(std::string()); - curl_easy_getinfo(curlhandle, CURLINFO_REDIRECT_URL, &redirect_url); + redirect_url = Util::CurlHandleGetInfoString(curlhandle, CURLINFO_REDIRECT_URL); } - if (!std::string(redirect_url).empty()) + if (!redirect_url.empty()) { long response_code; do { - curl_easy_setopt(curlhandle, CURLOPT_URL, redirect_url); + curl_easy_setopt(curlhandle, CURLOPT_URL, redirect_url.c_str()); result = curl_easy_perform(curlhandle); memory.str(std::string()); result = curl_easy_getinfo(curlhandle, CURLINFO_RESPONSE_CODE, &response_code); if ((response_code / 100) == 3) - curl_easy_getinfo(curlhandle, CURLINFO_REDIRECT_URL, &redirect_url); + redirect_url = Util::CurlHandleGetInfoString(curlhandle, CURLINFO_REDIRECT_URL); - std::string redir_url = std::string(redirect_url); boost::regex re(".*code=(.*?)([\?&].*|$)", boost::regex_constants::icase); boost::match_results what; - if (boost::regex_search(redir_url, what, re)) + if (boost::regex_search(redirect_url, what, re)) { auth_code = what[1]; if (!auth_code.empty()) @@ -444,7 +440,7 @@ int Website::Login(const std::string& email, const std::string& password) } while (result == CURLE_OK && (response_code / 100) == 3); } - curl_easy_setopt(curlhandle, CURLOPT_URL, redirect_url); + curl_easy_setopt(curlhandle, CURLOPT_URL, redirect_url.c_str()); curl_easy_setopt(curlhandle, CURLOPT_HTTPGET, 1); curl_easy_setopt(curlhandle, CURLOPT_MAXREDIRS, -1); curl_easy_setopt(curlhandle, CURLOPT_FOLLOWLOCATION, 1);