From 947b4574fa7998f027d3906e1f53acb9a7553c61 Mon Sep 17 00:00:00 2001 From: Jakub Stasiak Date: Fri, 14 Jun 2024 00:59:41 +0200 Subject: [PATCH] inet_ntop: fix the IPv6 leading zero sequence compression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per RFC 5952, ties for longest sequence of zero fields must be broken by choosing the earliest, but the implementation put the leading sequence of zeros at a disadvantage. That's because for example when compressing "0:0:0:10:0:0:0:10" the strspn(buf+i, ":0") call returns 6 for the first sequence and 7 for the second one – the second sequence has the benefit of a leading colon. Changing the condition to require beating the leading sequence by not one but two characters resolves the issue. --- src/network/inet_ntop.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/inet_ntop.c b/src/network/inet_ntop.c index 4bfef2c5..f442f47d 100644 --- a/src/network/inet_ntop.c +++ b/src/network/inet_ntop.c @@ -34,7 +34,12 @@ const char *inet_ntop(int af, const void *restrict a0, char *restrict s, socklen for (i=best=0, max=2; buf[i]; i++) { if (i && buf[i] != ':') continue; j = strspn(buf+i, ":0"); - if (j>max) best=i, max=j; + /* The leading sequence of zeros (best==0) is + * disadvantaged compared to sequences elsewhere + * as it doesn't have a leading colon. One extra + * character is required for another sequence to + * beat it fairly. */ + if (j>max+(best==0)) best=i, max=j; } if (max>3) { buf[best] = buf[best+1] = ':';