From e61325585d99268e6554298f4192ee15fe19e00f Mon Sep 17 00:00:00 2001 From: Steven Murray <Steven.Murray@cern.ch> Date: Tue, 1 Sep 2015 13:52:24 +0200 Subject: [PATCH] Added Utils::toUid() and Utils::toGid() --- common/UserIdentity.cpp | 5 +- common/Utils.cpp | 73 ++++++++++++++++++++++++++ common/Utils.hpp | 17 +++++++ common/UtilsTest.cpp | 110 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 202 insertions(+), 3 deletions(-) diff --git a/common/UserIdentity.cpp b/common/UserIdentity.cpp index c72c97b430..350523e4fd 100644 --- a/common/UserIdentity.cpp +++ b/common/UserIdentity.cpp @@ -19,14 +19,15 @@ #include "common/UserIdentity.hpp" #include <limits> +#include <unistd.h> #include <ostream> //------------------------------------------------------------------------------ // constructor //------------------------------------------------------------------------------ cta::UserIdentity::UserIdentity() throw(): - uid(std::numeric_limits<decltype(uid)>::max()), - gid(std::numeric_limits<decltype(gid)>::max()) {} + uid(std::numeric_limits<uid_t>::max()), + gid(std::numeric_limits<gid_t>::max()) {} //------------------------------------------------------------------------------ // constructor diff --git a/common/Utils.cpp b/common/Utils.cpp index c6f2c0de1d..ba6368a5a6 100644 --- a/common/Utils.cpp +++ b/common/Utils.cpp @@ -21,6 +21,7 @@ #include "common/Utils.hpp" #include <attr/xattr.h> +#include <limits> #include <memory> #include <shift/serrno.h> #include <sstream> @@ -377,6 +378,78 @@ uint16_t cta::Utils::toUint16(const std::string &str) { return value; } +//------------------------------------------------------------------------------ +// toUid +//------------------------------------------------------------------------------ +uid_t cta::Utils::toUid(const std::string &str) { + if(str.empty()) { + std::ostringstream msg; + msg << "Failed to convert empty string to uid_t: An empty string is not" + " a valid uid_t value"; + throw exception::Exception(msg.str()); + } + + errno = 0; + const long int value = strtol(str.c_str(), (char **) NULL, 10); + const int savedErrno = errno; + if(savedErrno) { + std::ostringstream msg; + msg << "Failed to convert \'" << str << "' to uid_t: " << + errnoToString(savedErrno); + throw exception::Exception(msg.str()); + } + + if(0 > value) { + std::ostringstream msg; + msg << "Failed to convert \'" << str << "' to uid_t: Negative number"; + throw exception::Exception(msg.str()); + } + + if(std::numeric_limits<uid_t>::max() < value) { + std::ostringstream msg; + msg << "Failed to convert \'" << str << "' to uid_t: Number too big"; + throw exception::Exception(msg.str()); + } + + return value; +} + +//------------------------------------------------------------------------------ +// toGid +//------------------------------------------------------------------------------ +gid_t cta::Utils::toGid(const std::string &str) { + if(str.empty()) { + std::ostringstream msg; + msg << "Failed to convert empty string to gid_t: An empty string is not" + " a valid gid_t value"; + throw exception::Exception(msg.str()); + } + + errno = 0; + const long int value = strtol(str.c_str(), (char **) NULL, 10); + const int savedErrno = errno; + if(savedErrno) { + std::ostringstream msg; + msg << "Failed to convert \'" << str << "' to gid_t: " << + errnoToString(savedErrno); + throw exception::Exception(msg.str()); + } + + if(0 > value) { + std::ostringstream msg; + msg << "Failed to convert \'" << str << "' to gid_t: Negative number"; + throw exception::Exception(msg.str()); + } + + if(std::numeric_limits<gid_t>::max() < value) { + std::ostringstream msg; + msg << "Failed to convert \'" << str << "' to gid_t: Number too big"; + throw exception::Exception(msg.str()); + } + + return value; +} + //------------------------------------------------------------------------------ // isValidUInt //------------------------------------------------------------------------------ diff --git a/common/Utils.hpp b/common/Utils.hpp index 334ff1c6dc..7d3bade4af 100644 --- a/common/Utils.hpp +++ b/common/Utils.hpp @@ -21,6 +21,7 @@ #include <list> #include <sstream> #include <string> +#include <unistd.h> #include <vector> namespace cta { @@ -182,6 +183,22 @@ public: */ static uint16_t toUint16(const std::string &str); + /** + * Converts the specified string to a uid. + * + * @param str The string. + * @return The uid. + */ + static uid_t toUid(const std::string &str); + + /** + * Converts the specified string to a gid. + * + * @param str The string. + * @return The gid. + */ + static gid_t toGid(const std::string &str); + /** * Checks if the specified string is a valid unsigned integer. * diff --git a/common/UtilsTest.cpp b/common/UtilsTest.cpp index ec8dfcba26..f1f8bb7184 100644 --- a/common/UtilsTest.cpp +++ b/common/UtilsTest.cpp @@ -275,7 +275,7 @@ TEST_F(cta_UtilsTest, errnoToString_EACCESS) { ASSERT_EQ(std::string("Permission denied"), str); } -TEST_F(cta_UtilsTest, toUint16_uint16_t) { +TEST_F(cta_UtilsTest, toUint16_12345) { using namespace cta; uint16_t i = 0; @@ -320,6 +320,114 @@ TEST_F(cta_UtilsTest, toUint16_too_big) { ASSERT_THROW(Utils::toUint16("65536"), std::exception); } +TEST_F(cta_UtilsTest, toUid_12345) { + using namespace cta; + + uid_t i = 0; + + ASSERT_NO_THROW(i = Utils::toUid("12345")); + ASSERT_EQ((uid_t)12345, i); +} + +TEST_F(cta_UtilsTest, toUid_zero) { + using namespace cta; + + uid_t i = 0; + + ASSERT_NO_THROW(i = Utils::toUid("0")); + ASSERT_EQ((uid_t)0, i); +} + +TEST_F(cta_UtilsTest, toUid_max) { + using namespace cta; + + std::ostringstream oss; + oss << std::numeric_limits<uid_t>::max(); + + uid_t i = 0; + + ASSERT_NO_THROW(i = Utils::toUid(oss.str())); + ASSERT_EQ(std::numeric_limits<uid_t>::max(), i); +} + +TEST_F(cta_UtilsTest, toUid_empty_string) { + using namespace cta; + + ASSERT_THROW(Utils::toUid(""), std::exception); +} + +TEST_F(cta_UtilsTest, toUid_negative) { + using namespace cta; + + ASSERT_THROW(Utils::toUid("-12345"), std::exception); +} + +TEST_F(cta_UtilsTest, toUid_too_big) { + using namespace cta; + + const uint64_t tooBig = (uint64_t)(std::numeric_limits<uid_t>::max()) + + (uint64_t)1; + + std::ostringstream oss; + oss << tooBig; + + ASSERT_THROW(Utils::toUid(oss.str()), std::exception); +} + +TEST_F(cta_UtilsTest, toGid_12345) { + using namespace cta; + + gid_t i = 0; + + ASSERT_NO_THROW(i = Utils::toGid("12345")); + ASSERT_EQ((gid_t)12345, i); +} + +TEST_F(cta_UtilsTest, toGid_zero) { + using namespace cta; + + gid_t i = 0; + + ASSERT_NO_THROW(i = Utils::toGid("0")); + ASSERT_EQ((gid_t)0, i); +} + +TEST_F(cta_UtilsTest, toGid_max) { + using namespace cta; + + std::ostringstream oss; + oss << std::numeric_limits<gid_t>::max(); + + gid_t i = 0; + + ASSERT_NO_THROW(i = Utils::toGid(oss.str())); + ASSERT_EQ(std::numeric_limits<gid_t>::max(), i); +} + +TEST_F(cta_UtilsTest, toGid_empty_string) { + using namespace cta; + + ASSERT_THROW(Utils::toGid(""), std::exception); +} + +TEST_F(cta_UtilsTest, toGid_negative) { + using namespace cta; + + ASSERT_THROW(Utils::toGid("-12345"), std::exception); +} + +TEST_F(cta_UtilsTest, toGid_too_big) { + using namespace cta; + + const uint64_t tooBig = (uint64_t)(std::numeric_limits<gid_t>::max()) + + (uint64_t)1; + + std::ostringstream oss; + oss << tooBig; + + ASSERT_THROW(Utils::toGid(oss.str()), std::exception); +} + TEST_F(cta_UtilsTest, isValidUInt_unsigned_int) { using namespace cta; -- GitLab