Skip to content

Commit f9f7714

Browse files
committed
Fix pony_os_ip_string returning NULL for valid IP addresses
inet_ntop returns non-NULL on success, but the check was inverted, so valid IPs returned NULL and only failures fell through to use the result buffer. Closes #5048
1 parent 8d07307 commit f9f7714

3 files changed

Lines changed: 33 additions & 1 deletion

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## Fix pony_os_ip_string returning NULL for valid IP addresses
2+
3+
The runtime function `pony_os_ip_string` had an inverted check on the result of `inet_ntop`. Since `inet_ntop` returns non-NULL on success, the inverted condition meant the function returned NULL for every valid IP address and only attempted to use the result buffer on failure.
4+
5+
Any code that called `pony_os_ip_string` with a valid IPv4 or IPv6 address got NULL back. The most visible downstream effect was in the `ssl` library, where `X509.all_names()` calls this function to convert IP SANs from certificates into strings. The NULL result produced empty strings, corrupting the names array and breaking hostname verification for certificates that use IP SANs.

packages/net/_test.pony

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use "files"
22
use "pony_test"
33

4+
use @pony_os_ip_string[Pointer[U8]](src: Pointer[U8] tag, len: I32)
5+
46
primitive TimeoutValue
57
fun apply(): U64 =>
68
ifdef windows then
@@ -16,6 +18,7 @@ actor \nodoc\ Main is TestList
1618

1719
fun tag tests(test: PonyTest) =>
1820
// Tests below function across all systems and are listed alphabetically
21+
test(_TestOsIpString)
1922
test(_TestTCPConnectionFailed)
2023
test(_TestTCPExpect)
2124
test(_TestTCPExpectOverBufferSize)
@@ -837,3 +840,27 @@ actor \nodoc\ _TCPConnectionToClosedServerFailedConnector
837840
host,
838841
port)
839842
h.dispose_when_done(connection)
843+
844+
class \nodoc\ _TestOsIpString is UnitTest
845+
"""
846+
Regression test for https://github.com/ponylang/ponyc/issues/5048.
847+
848+
pony_os_ip_string had an inverted inet_ntop check that returned NULL
849+
for valid IP addresses.
850+
"""
851+
fun name(): String => "net/pony_os_ip_string"
852+
853+
fun apply(h: TestHelper) =>
854+
// IPv4: 127.0.0.1
855+
let ipv4 = [as U8: 0x7F; 0x00; 0x00; 0x01]
856+
let ipv4_str: String val = recover
857+
String.from_cstring(@pony_os_ip_string(ipv4.cpointer(), I32(4)))
858+
end
859+
h.assert_eq[String](ipv4_str, "127.0.0.1")
860+
861+
// IPv6: ::1
862+
let ipv6 = [as U8: 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 1]
863+
let ipv6_str: String val = recover
864+
String.from_cstring(@pony_os_ip_string(ipv6.cpointer(), I32(16)))
865+
end
866+
h.assert_eq[String](ipv6_str, "::1")

src/libponyrt/lang/socket.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@ PONY_API char* pony_os_ip_string(void* src, int len)
877877
if(family == -1)
878878
return NULL;
879879

880-
if(inet_ntop(family, src, dst, INET6_ADDRSTRLEN))
880+
if(!inet_ntop(family, src, dst, INET6_ADDRSTRLEN))
881881
return NULL;
882882

883883
size_t dstlen = strlen(dst);

0 commit comments

Comments
 (0)