From f50544397f54b54f9bbf1fafda6d1c71e8307c87 Mon Sep 17 00:00:00 2001 From: Ian Duncan <76043277+dr8co@users.noreply.github.com> Date: Wed, 22 Nov 2023 22:21:55 +0300 Subject: [PATCH] Handle thread-local exceptions Thread-local exceptions caused the previous implementation to abort, which doesn't perform any cleanup, so it was necessary to handle the exceptions thread-locally and to cause the program to exit (i.e., terminate normally, with cleanup), to enhance the security and safety of the program and to protect against memory leaks. --- src/passwordManager/passwords.cpp | 37 ++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/passwordManager/passwords.cpp b/src/passwordManager/passwords.cpp index 74914c4..66ef318 100644 --- a/src/passwordManager/passwords.cpp +++ b/src/passwordManager/passwords.cpp @@ -139,10 +139,16 @@ encryptDecryptRange(privacy::vector &passwords, const privacy:: if (start > end || end > passwords.size()) throw std::range_error("Invalid range."); - // Encrypt/decrypt the password field - for (std::size_t i = start; i < end; ++i) { - std::get<2>(passwords[i]) = encrypt ? encryptStringWithMoreRounds(std::get<2>(passwords[i]), key) - : decryptStringWithMoreRounds(std::string{std::get<2>(passwords[i])}, key); + try { + // Encrypt/decrypt the password field + for (std::size_t i = start; i < end; ++i) { + std::get<2>(passwords[i]) = encrypt ? encryptStringWithMoreRounds(std::get<2>(passwords[i]), key) + : decryptStringWithMoreRounds(std::string{std::get<2>(passwords[i])}, + key); + } + } catch (const std::exception &ex) { + printColor(std::format("Error: {}", ex.what()), 'r', true, std::cerr); + std::exit(1); } } @@ -158,16 +164,21 @@ encryptDecryptRangeAllFields(privacy::vector &passwords, const if (start > end || end > passwords.size()) throw std::range_error("Invalid range."); - // Encrypt/decrypt all fields - for (std::size_t i = start; i < end; ++i) { - std::get<0>(passwords[i]) = encrypt ? encryptString(std::get<0>(passwords[i]), key) - : decryptString(std::string{std::get<0>(passwords[i])}, key); + try { + // Encrypt/decrypt all fields + for (std::size_t i = start; i < end; ++i) { + std::get<0>(passwords[i]) = encrypt ? encryptString(std::get<0>(passwords[i]), key) + : decryptString(std::string{std::get<0>(passwords[i])}, key); - std::get<1>(passwords[i]) = encrypt ? encryptString(std::get<1>(passwords[i]), key) - : decryptString(std::string{std::get<1>(passwords[i])}, key); + std::get<1>(passwords[i]) = encrypt ? encryptString(std::get<1>(passwords[i]), key) + : decryptString(std::string{std::get<1>(passwords[i])}, key); - std::get<2>(passwords[i]) = encrypt ? encryptString(std::get<2>(passwords[i]), key) - : decryptString(std::string{std::get<2>(passwords[i])}, key); + std::get<2>(passwords[i]) = encrypt ? encryptString(std::get<2>(passwords[i]), key) + : decryptString(std::string{std::get<2>(passwords[i])}, key); + } + } catch (const std::exception &ex) { + printColor(std::format("Error: {}", ex.what()), 'r', true, std::cerr); + std::exit(1); } } @@ -238,7 +249,7 @@ bool savePasswords(privacy::vector &passwords, const std::strin } catch (const std::exception &ex) { std::cerr << ex.what() << std::endl; - } catch (...) {} + } catch (...) {} // we're not 'swallowing' this, we just don't want to have a specific message for it. std::cerr << std::format("Failed to open the password file ({}) for writing.\n", filePath); return false;