Fix core dump with libcurl >= 7.87.0

Relying on automatic object allocation caused curl_global_cleanup() to be called before destructor cleaned up curl handles causing segfault.
Use dynamic object allocation and delete objects before calling curl_global_cleanup() so destructor is executed before global cleanup.
This commit is contained in:
Sude 2022-12-28 00:17:19 +02:00
parent e5d347d5b2
commit 6ce6aeb1dc

View File

@ -636,32 +636,33 @@ int main(int argc, char *argv[])
// Init curl globally // Init curl globally
curl_global_init(CURL_GLOBAL_ALL); curl_global_init(CURL_GLOBAL_ALL);
Downloader downloader; Downloader *downloader = new Downloader;
int iLoginTries = 0; int iLoginTries = 0;
bool bLoginOK = false; bool bLoginOK = false;
// Login because --login was used // Login because --login was used
if (Globals::globalConfig.bLogin) if (Globals::globalConfig.bLogin)
bLoginOK = downloader.login(); bLoginOK = downloader->login();
bool bIsLoggedin = downloader.isLoggedIn(); bool bIsLoggedin = downloader->isLoggedIn();
if (!bIsLoggedin) if (!bIsLoggedin)
Globals::globalConfig.bLogin = true; Globals::globalConfig.bLogin = true;
// Login because we are not logged in // Login because we are not logged in
while (iLoginTries++ < Globals::globalConfig.iRetries && !bIsLoggedin) while (iLoginTries++ < Globals::globalConfig.iRetries && !bIsLoggedin)
{ {
bLoginOK = downloader.login(); bLoginOK = downloader->login();
if (bLoginOK) if (bLoginOK)
{ {
bIsLoggedin = downloader.isLoggedIn(); bIsLoggedin = downloader->isLoggedIn();
} }
} }
// Login failed, cleanup // Login failed, cleanup
if (!bLoginOK && !bIsLoggedin) if (!bLoginOK && !bIsLoggedin)
{ {
delete downloader;
curl_global_cleanup(); curl_global_cleanup();
return 1; return 1;
} }
@ -725,6 +726,7 @@ int main(int argc, char *argv[])
Util::setFilePermissions(Globals::globalConfig.sConfigFilePath, boost::filesystem::owner_read | boost::filesystem::owner_write); Util::setFilePermissions(Globals::globalConfig.sConfigFilePath, boost::filesystem::owner_read | boost::filesystem::owner_write);
if (Globals::globalConfig.bSaveConfig) if (Globals::globalConfig.bSaveConfig)
{ {
delete downloader;
curl_global_cleanup(); curl_global_cleanup();
return 0; return 0;
} }
@ -732,6 +734,7 @@ int main(int argc, char *argv[])
else else
{ {
std::cerr << "Failed to create config: " << Globals::globalConfig.sConfigFilePath << std::endl; std::cerr << "Failed to create config: " << Globals::globalConfig.sConfigFilePath << std::endl;
delete downloader;
curl_global_cleanup(); curl_global_cleanup();
return 1; return 1;
} }
@ -745,20 +748,23 @@ int main(int argc, char *argv[])
if (!Globals::globalConfig.bRespectUmask) if (!Globals::globalConfig.bRespectUmask)
Util::setFilePermissions(Globals::globalConfig.sConfigFilePath, boost::filesystem::owner_read | boost::filesystem::owner_write); Util::setFilePermissions(Globals::globalConfig.sConfigFilePath, boost::filesystem::owner_read | boost::filesystem::owner_write);
delete downloader;
curl_global_cleanup(); curl_global_cleanup();
return 0; return 0;
} }
else else
{ {
std::cerr << "Failed to create config: " << Globals::globalConfig.sConfigFilePath << std::endl; std::cerr << "Failed to create config: " << Globals::globalConfig.sConfigFilePath << std::endl;
delete downloader;
curl_global_cleanup(); curl_global_cleanup();
return 1; return 1;
} }
} }
bool bInitOK = downloader.init(); bool bInitOK = downloader->init();
if (!bInitOK) if (!bInitOK)
{ {
delete downloader;
curl_global_cleanup(); curl_global_cleanup();
return 1; return 1;
} }
@ -766,32 +772,32 @@ int main(int argc, char *argv[])
int res = 0; int res = 0;
if (Globals::globalConfig.bShowWishlist) if (Globals::globalConfig.bShowWishlist)
downloader.showWishlist(); downloader->showWishlist();
else if (Globals::globalConfig.bUpdateCache) else if (Globals::globalConfig.bUpdateCache)
downloader.updateCache(); downloader->updateCache();
else if (Globals::globalConfig.bNotifications) else if (Globals::globalConfig.bNotifications)
downloader.checkNotifications(); downloader->checkNotifications();
else if (bClearUpdateNotifications) else if (bClearUpdateNotifications)
downloader.clearUpdateNotifications(); downloader->clearUpdateNotifications();
else if (!vFileIdStrings.empty()) else if (!vFileIdStrings.empty())
{ {
for (std::vector<std::string>::iterator it = vFileIdStrings.begin(); it != vFileIdStrings.end(); it++) for (std::vector<std::string>::iterator it = vFileIdStrings.begin(); it != vFileIdStrings.end(); it++)
{ {
res |= downloader.downloadFileWithId(*it, Globals::globalConfig.sOutputFilename) ? 1 : 0; res |= downloader->downloadFileWithId(*it, Globals::globalConfig.sOutputFilename) ? 1 : 0;
} }
} }
else if (Globals::globalConfig.bRepair) // Repair file else if (Globals::globalConfig.bRepair) // Repair file
downloader.repair(); downloader->repair();
else if (Globals::globalConfig.bDownload) // Download games else if (Globals::globalConfig.bDownload) // Download games
downloader.download(); downloader->download();
else if (Globals::globalConfig.bListDetails || Globals::globalConfig.bList) // Detailed list of games/extras else if (Globals::globalConfig.bListDetails || Globals::globalConfig.bList) // Detailed list of games/extras
res = downloader.listGames(); res = downloader->listGames();
else if (Globals::globalConfig.bListTags) // List tags else if (Globals::globalConfig.bListTags) // List tags
res = downloader.listTags(); res = downloader->listTags();
else if (!Globals::globalConfig.sOrphanRegex.empty()) // Check for orphaned files if regex for orphans is set else if (!Globals::globalConfig.sOrphanRegex.empty()) // Check for orphaned files if regex for orphans is set
downloader.checkOrphans(); downloader->checkOrphans();
else if (Globals::globalConfig.bCheckStatus) else if (Globals::globalConfig.bCheckStatus)
downloader.checkStatus(); downloader->checkStatus();
else if (!galaxy_product_id_show_builds.empty()) else if (!galaxy_product_id_show_builds.empty())
{ {
int build_index = -1; int build_index = -1;
@ -801,7 +807,7 @@ int main(int argc, char *argv[])
{ {
build_index = std::stoi(tokens[1]); build_index = std::stoi(tokens[1]);
} }
downloader.galaxyShowBuilds(product_id, build_index); downloader->galaxyShowBuilds(product_id, build_index);
} }
else if (!galaxy_product_id_show_cloud_paths.empty()) else if (!galaxy_product_id_show_cloud_paths.empty())
{ {
@ -812,7 +818,7 @@ int main(int argc, char *argv[])
{ {
build_index = std::stoi(tokens[1]); build_index = std::stoi(tokens[1]);
} }
downloader.galaxyShowCloudSaves(product_id, build_index); downloader->galaxyShowCloudSaves(product_id, build_index);
} }
else if (!galaxy_product_id_show_local_cloud_paths.empty()) else if (!galaxy_product_id_show_local_cloud_paths.empty())
{ {
@ -823,7 +829,7 @@ int main(int argc, char *argv[])
{ {
build_index = std::stoi(tokens[1]); build_index = std::stoi(tokens[1]);
} }
downloader.galaxyShowLocalCloudSaves(product_id, build_index); downloader->galaxyShowLocalCloudSaves(product_id, build_index);
} }
else if (!galaxy_product_cloud_saves_delete.empty()) else if (!galaxy_product_cloud_saves_delete.empty())
{ {
@ -834,7 +840,7 @@ int main(int argc, char *argv[])
{ {
build_index = std::stoi(tokens[1]); build_index = std::stoi(tokens[1]);
} }
downloader.deleteCloudSaves(product_id, build_index); downloader->deleteCloudSaves(product_id, build_index);
} }
else if (!galaxy_product_id_install.empty()) else if (!galaxy_product_id_install.empty())
{ {
@ -845,7 +851,7 @@ int main(int argc, char *argv[])
{ {
build_index = std::stoi(tokens[1]); build_index = std::stoi(tokens[1]);
} }
downloader.galaxyInstallGame(product_id, build_index, Globals::globalConfig.dlConf.iGalaxyArch); downloader->galaxyInstallGame(product_id, build_index, Globals::globalConfig.dlConf.iGalaxyArch);
} }
else if (!galaxy_product_cloud_saves.empty()) { else if (!galaxy_product_cloud_saves.empty()) {
int build_index = -1; int build_index = -1;
@ -855,7 +861,7 @@ int main(int argc, char *argv[])
{ {
build_index = std::stoi(tokens[1]); build_index = std::stoi(tokens[1]);
} }
downloader.downloadCloudSaves(product_id, build_index); downloader->downloadCloudSaves(product_id, build_index);
} }
else if (!galaxy_upload_product_cloud_saves.empty()) { else if (!galaxy_upload_product_cloud_saves.empty()) {
int build_index = -1; int build_index = -1;
@ -865,7 +871,7 @@ int main(int argc, char *argv[])
{ {
build_index = std::stoi(tokens[1]); build_index = std::stoi(tokens[1]);
} }
downloader.uploadCloudSaves(product_id, build_index); downloader->uploadCloudSaves(product_id, build_index);
} }
else else
{ {
@ -879,8 +885,9 @@ int main(int argc, char *argv[])
// Orphan check was called at the same time as download. Perform it after download has finished // Orphan check was called at the same time as download. Perform it after download has finished
if (!Globals::globalConfig.sOrphanRegex.empty() && Globals::globalConfig.bDownload) if (!Globals::globalConfig.sOrphanRegex.empty() && Globals::globalConfig.bDownload)
downloader.checkOrphans(); downloader->checkOrphans();
delete downloader;
curl_global_cleanup(); curl_global_cleanup();
return res; return res;