mirror of
https://github.com/fpagliughi/sockpp.git
synced 2026-01-12 00:04:45 +08:00
#56 handling unix paths with maximum length (no NUL term)
This commit is contained in:
@@ -74,8 +74,8 @@ public:
|
||||
/** The address family for this type of address */
|
||||
static constexpr sa_family_t ADDRESS_FAMILY = AF_UNIX;
|
||||
|
||||
// TODO: This only applies to Linux
|
||||
static constexpr size_t MAX_PATH_NAME = 108;
|
||||
/** The max length of the file path */
|
||||
static constexpr size_t MAX_PATH_NAME = sizeof(sockaddr_un::sun_path);
|
||||
|
||||
/**
|
||||
* Constructs an empty address.
|
||||
@@ -83,8 +83,8 @@ public:
|
||||
*/
|
||||
unix_address() : addr_() {}
|
||||
/**
|
||||
* Constructs an address for the specified path.
|
||||
* @param path The
|
||||
* Constructs an address given the specified path.
|
||||
* @param path The path to the socket file.
|
||||
*/
|
||||
unix_address(const std::string& path);
|
||||
/**
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
* initialized as a UNIX-domain address (i.e. family is not
|
||||
* AF_UNIX)
|
||||
*/
|
||||
unix_address(const sockaddr_un& addr) : addr_(addr) {}
|
||||
unix_address(const sockaddr_un& addr);
|
||||
/**
|
||||
* Constructs the address by copying the specified address.
|
||||
* @param addr The other address
|
||||
@@ -125,7 +125,9 @@ public:
|
||||
* Gets the path to which this address refers.
|
||||
* @return The path to which this address refers.
|
||||
*/
|
||||
std::string path() const { return std::string(addr_.sun_path); }
|
||||
std::string path() const {
|
||||
return std::string(addr_.sun_path, strnlen(addr_.sun_path, MAX_PATH_NAME));
|
||||
}
|
||||
/**
|
||||
* Gets the size of the address structure.
|
||||
* Note: In this implementation, this should return sizeof(this) but
|
||||
@@ -170,7 +172,7 @@ public:
|
||||
* "unix:<path>"
|
||||
*/
|
||||
std::string to_string() const {
|
||||
return std::string("unix:") + std::string(addr_.sun_path);
|
||||
return std::string("unix:") + path();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -55,17 +55,20 @@ unix_address::unix_address(const string& path)
|
||||
::strncpy(addr_.sun_path, path.c_str(), MAX_PATH_NAME);
|
||||
}
|
||||
|
||||
unix_address::unix_address(const sockaddr& addr)
|
||||
unix_address::unix_address(const sockaddr& addr) : addr_{}
|
||||
{
|
||||
auto domain = addr.sa_family;
|
||||
if (domain != AF_UNIX)
|
||||
if (addr.sa_family != ADDRESS_FAMILY)
|
||||
throw std::invalid_argument("Not a UNIX-domain address");
|
||||
|
||||
// TODO: We should check the path, or at least see that it has
|
||||
// proper NUL termination.
|
||||
std::memcpy(&addr_, &addr, sizeof(sockaddr));
|
||||
}
|
||||
|
||||
unix_address::unix_address(const sockaddr_un& addr) : addr_(addr)
|
||||
{
|
||||
if (addr.sun_family != ADDRESS_FAMILY)
|
||||
throw std::invalid_argument("Not a UNIX-domain address");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
ostream& operator<<(ostream& os, const unix_address& addr)
|
||||
|
||||
@@ -46,6 +46,15 @@ using namespace sockpp;
|
||||
|
||||
std::string PATH { "/tmp/sock" };
|
||||
|
||||
TEST_CASE("unix_address sizes", "[address]") {
|
||||
#if defined(__linux__)
|
||||
REQUIRE(108 == unix_address::MAX_PATH_NAME);
|
||||
#endif
|
||||
|
||||
// On most systems, size should be 104, 108, or larger.
|
||||
REQUIRE(unix_address::MAX_PATH_NAME > 64);
|
||||
}
|
||||
|
||||
TEST_CASE("unix_address default constructor", "[address]") {
|
||||
unix_address addr;
|
||||
|
||||
@@ -65,8 +74,9 @@ TEST_CASE("unix_address path constructor", "[address]") {
|
||||
|
||||
// Check the low-level struct
|
||||
REQUIRE(AF_UNIX == addr.sockaddr_un_ptr()->sun_family);
|
||||
REQUIRE(0 == strcmp(PATH.c_str(),
|
||||
(const char*) &addr.sockaddr_un_ptr()->sun_path));
|
||||
REQUIRE(0 == strncmp(PATH.c_str(),
|
||||
(const char*) &addr.sockaddr_un_ptr()->sun_path,
|
||||
unix_address::MAX_PATH_NAME));
|
||||
|
||||
SECTION("copy constructor") {
|
||||
unix_address addr2(addr);
|
||||
@@ -77,8 +87,9 @@ TEST_CASE("unix_address path constructor", "[address]") {
|
||||
|
||||
// Check the low-level struct
|
||||
REQUIRE(AF_UNIX == addr2.sockaddr_un_ptr()->sun_family);
|
||||
REQUIRE(0 == strcmp(PATH.c_str(),
|
||||
(const char*) &addr2.sockaddr_un_ptr()->sun_path));
|
||||
REQUIRE(0 == strncmp(PATH.c_str(),
|
||||
(const char*) &addr2.sockaddr_un_ptr()->sun_path,
|
||||
unix_address::MAX_PATH_NAME));
|
||||
}
|
||||
|
||||
SECTION("sockaddr conversions") {
|
||||
@@ -91,9 +102,33 @@ TEST_CASE("unix_address path constructor", "[address]") {
|
||||
|
||||
// Check the low-level struct
|
||||
REQUIRE(AF_UNIX == addr2.sockaddr_un_ptr()->sun_family);
|
||||
REQUIRE(0 == strcmp(PATH.c_str(),
|
||||
(const char*) &(addr2.sockaddr_un_ptr()->sun_path)));
|
||||
REQUIRE(0 == strncmp(PATH.c_str(),
|
||||
(const char*) &addr2.sockaddr_un_ptr()->sun_path,
|
||||
unix_address::MAX_PATH_NAME));
|
||||
}
|
||||
|
||||
SECTION("full path") {
|
||||
// Test what happens if 'sun_path' is full, with no NUL termination
|
||||
std::string path;
|
||||
sockaddr_un unaddr;
|
||||
unaddr.sun_family = AF_UNIX;
|
||||
|
||||
for (size_t i=0; i<unix_address::MAX_PATH_NAME; ++i) {
|
||||
char c = 'a' + (i % 26);
|
||||
unaddr.sun_path[i] = c;
|
||||
path.push_back(c);
|
||||
}
|
||||
|
||||
// sockaddr_un constructor
|
||||
unix_address addr(unaddr);
|
||||
REQUIRE(unix_address::MAX_PATH_NAME == addr.path().size());
|
||||
REQUIRE(path == addr.path());
|
||||
|
||||
// path (string) constructor
|
||||
unix_address addr2(path);
|
||||
REQUIRE(unix_address::MAX_PATH_NAME == addr2.path().size());
|
||||
REQUIRE(path == addr2.path());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("unix_address sockaddr_un constructor", "[address]") {
|
||||
@@ -109,16 +144,14 @@ TEST_CASE("unix_address sockaddr_un constructor", "[address]") {
|
||||
|
||||
// Check the low-level struct
|
||||
REQUIRE(AF_UNIX == addr.sockaddr_un_ptr()->sun_family);
|
||||
REQUIRE(0 == strcmp(PATH.c_str(),
|
||||
(const char*) &addr.sockaddr_un_ptr()->sun_path));
|
||||
REQUIRE(0 == strncmp(PATH.c_str(),
|
||||
(const char*) &addr.sockaddr_un_ptr()->sun_path,
|
||||
unix_address::MAX_PATH_NAME));
|
||||
|
||||
// TODO: Restore this when all address checks in place
|
||||
/*
|
||||
SECTION("reject bad sockaddr_un") {
|
||||
unaddr.sun_family = AF_INET;
|
||||
REQUIRE_THROWS_AS([&] {
|
||||
unix_address addr2(unaddr);
|
||||
}(), std::invalid_argument);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user