Skip to content

Compress the longest run of zero fields in IPv6#to_s - #160

Open
afurm wants to merge 1 commit into
ruby:masterfrom
afurm:ipv6-to-s-longest-zero-run
Open

afurm wants to merge 1 commit into
ruby:masterfrom
afurm:ipv6-to-s-longest-zero-run

Conversation

@afurm

@afurm afurm commented Oct 23, 2026

Copy link
Copy Markdown
Member

Resolv::IPv6#to_s always replaces the first run of two or more zero fields with ::. RFC 5952 Section 4.2.3 asks for the longest run to be shortened, and only falls back to the first one when the runs are equally long:

Resolv::IPv6.create("1:0:0:1:0:0:0:1").to_s
# before: "1::1:0:0:0:1"
# after:  "1:0:0:1::1"   (same as IPAddr / inet_ntop)

Since Resolv.getaddress and friends return these strings, an AAAA record like that didn't match the text other tools produce for the same address (this was the OpenSSH known_hosts case from #24).

I replaced the regexp with a small scan over the eight fields that picks the longest run of two or more zeros, keeping the existing behaviour of never compressing a single zero field (Section 4.2.2). One existing expectation in test_ipv6_to_s encoded the old output, so I updated it and added a few more cases, including the RFC's own tie example (2001:db8::1:0:0:1).

As an extra check I compared the output with IPAddr#to_s for 200k random addresses with lots of zero fields (skipping the IPv4-mapped ones, which IPAddr prints in dotted form) and they all matched, and every result round-trips through Resolv::IPv6.create.

RFC 5952 Section 4.2.3 says the longest run of consecutive zero fields
must be shortened with "::", and only when runs are equally long should
the first one be used. The regexp in IPv6#to_s always replaced the
first run of two or more zeros, so 1:0:0:1:0:0:0:1 came out as
1::1:0:0:0:1 instead of 1:0:0:1::1.

This matters for addresses returned by Resolv.getaddress and friends,
which no longer match the canonical text other tools (IPAddr, OpenSSH
known_hosts, inet_ntop) produce for the same address.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant