From 395f5e53709aa2bee45de13d66e5a0706cf82dad Mon Sep 17 00:00:00 2001 From: "Justin R. Wilson" Date: Wed, 21 Jun 2023 11:28:26 -0500 Subject: [PATCH] `ACE_INET_Addr::set` errantly succeeds when ACE_LACKS_GETSERVBYNAME Problem ------- Calling `set("1.2.3.4")` on an ACE_INET_Addr eventually tries to part it as a port name. When `ACE_LACKS_GETSERVBYNAME`, this succeeds returning port number 0 with the reset address. When port names are not expected, this breaks a useful idiom of parsing addresses that may or may not contain port numbers: ACE_INET_Addr addr; if (addr.set(x) == 0) { // Success, address contained a port number } else if (addr.set(u_short(0), x) == 0) { // Success, address did not contain a port number. } else { // Fail } Solution -------- Return -1 for the port number when `ACE_LACKS_GETSERVBYNAME`. --- ACE/ace/INET_Addr.cpp | 3 +-- ACE/tests/INET_Addr_Test.cpp | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/ACE/ace/INET_Addr.cpp b/ACE/ace/INET_Addr.cpp index 58140d71ad428..25a1fb5d74fb7 100644 --- a/ACE/ace/INET_Addr.cpp +++ b/ACE/ace/INET_Addr.cpp @@ -468,12 +468,11 @@ static int get_port_number_from_name (const char port_name[], } // We try to resolve port number from its name. + port_number = -1; #if defined (ACE_LACKS_GETSERVBYNAME) - port_number = 0; ACE_UNUSED_ARG (port_name); ACE_UNUSED_ARG (protocol); #else - port_number = -1; servent sentry; ACE_SERVENT_DATA buf; servent *sp = ACE_OS::getservbyname_r (port_name, diff --git a/ACE/tests/INET_Addr_Test.cpp b/ACE/tests/INET_Addr_Test.cpp index 2a7e69a51bf91..b74c8b2184acd 100644 --- a/ACE/tests/INET_Addr_Test.cpp +++ b/ACE/tests/INET_Addr_Test.cpp @@ -158,6 +158,43 @@ static bool test_multiple () return success; } +static bool test_port_names() +{ + bool success = true; + + ACE_INET_Addr addr; + +#if defined (ACE_LACKS_GETSERVBYNAME) + // Since we don't have getservbyname, the call to set should fail. + // Check that the call does in fact fail. + if (addr.set("telnet") == 0) + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("set with 'telnet' succeeded (expected failure)\n"))); + success = false; + } +#else + if (addr.set("telnet") != 0) + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("set with 'telnet' failed (expected success)\n"))); + success = false; + } + + if (addr != ACE_INET_Addr("0.0.0.0:23")) + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("set with 'telnet' failed to yield correct address\n"))); + success = false; + } +#endif /* ACE_LACKS_GETSERVBYNAME */ + + if (addr.set("not a port name") == 0) + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("set with 'not a port name' succeeded (expected failure)\n"))); + success = false; + } + + return success; +} + struct Address { const char* name; bool loopback; @@ -561,6 +598,9 @@ int run_main (int, ACE_TCHAR *[]) status = 1; } + if (!test_port_names ()) + status = 1; + ACE_END_TEST; return status;