Changes for version 4.080_03 - 2026-09-30 (TRIAL RELEASE)

  • Reformat the test files with perltidy's default profile. Nine of them were indented with tabs while the other 140 used spaces, and .editorconfig asks for four columns of spaces, so t/ is now internally consistent for the first time. Whitespace is the only thing that moved, except for four semicolons perltidy deletes by default, being ones that are simply empty statements: the one after "sub BASE_LEN () { 7 };" in t/043, and one standing before a closing brace in each of t/087, t/096 and t/097. None of them changes what the code does.
  • Tabs survive in six files, inside comments that use them to line up columns in a table of test vectors. perltidy does not rewrite comment text, which is the right call, so those stay.
  • Checked by stripping all whitespace from each file before and after, which is the only guarantee perltidy actually makes, so those four semicolons are the whole of the difference. The suite passes either way: 160 files and 2927 tests from dzil test --all, and 160 files and 2531 tests in each of the XS and pure Perl built distributions.
  • No .perltidyrc is checked in, so this records the result rather than the settings that produced it, and nothing stops the files drifting apart again.
  • Name an undefined packed argument in the error, instead of warning first and then reporting a length of zero. The guards read their argument with length() and then did arithmetic or a comparison on the result, so an undef reached an operator first and perl warned about a value inside the library, at a line the caller cannot act on, before the check that names the function could run: inet_ntoa(undef) Use of uninitialized value in numeric eq (==), at InetBase.pm line 332 Bad arg length for ...::inet_ntoa, length is should be 4 hasbits(undef) Use of uninitialized value in numeric ne (!=), at UtilPP.pm line 137 Bad arg length for ...::hasbits, length is 0, should be 128 Both halves were wrong. The zero described a length nobody passed, and inet_ntoa interpolated an empty string because length(undef) is the empty string, so its message named the function and the expected width but no length at all. The message now says the length is undefined, and nothing warns on the way to it.
  • Fixed in both implementations, which have to agree: NetAddr::IP::Util is native by default and falls back to UtilPP, and the XS half got there differently. It declares its arguments as SV *, and SvPV turned an undefined argument into an empty string with a length of zero without complaining, so it reported the same misleading zero and perl's "Use of uninitialized value in subroutine entry" warning fired from the caller's line. Each XS function now tests SvOK before it calls SvPV.
  • inet_ntoa and ipv6_ntoa are pure perl with no XS counterpart, so they only needed the guard. ipv6_ntoa was also handing an undefined argument to Socket6::inet_ntop, which reported a length of 0 for something that had none.
  • A wrong but defined length is still measured and reported as before, so "ab" still gives 2 and not undefined.
  • Fix addition and subtraction accepting a constant that is not a number (GH#89). The guard compared $const == int($const), and perl numifies both sides first, so a string passed as its leading digits or as zero:
    • '5abc' added or subtracted 5
    • '0x10' and '0b11' added 0, which reads as no change at all
  • looks_like_number now runs ahead of the guard, and subtraction negates only what is a number so the guard sees the original otherwise. Hex, binary, 0o and empty strings are rejected. Padded and exponent strings, and a Math::BigInt constant, are unaffected. The POD in both IP.pm and Lite.pm said only that the constant must be an integer, and now says a non-numeric string croaks.
  • Keep the documented behaviour for a missing or zero constant, which returns a copy. Nothing tested it before, so the new tests pin it: undef and the empty string still return a copy for both operators, where subtraction previously died inside the negation and addition returned a copy.
  • Fix both SYNOPSIS use lists, which carried their annotations as qw() members, so each module tried to import a symbol named DEPRECATED and Lite.pm one named ! as well (GH#83)
  • Consolidate the scattered deprecation notes in IP.pm and Lite.pm into a DEPRECATED section under EXPORT_OK, and state there that everything listed is going in version 5:
    • the promise was only ever attached to a markdown ###### banner in a POD verbatim block, and in Lite.pm that sat 58 lines into the new_cis6 item body
    • :rfc3021 said only "a future version", and new_cis and new_cis6 carried no removal version at all
    • :rfc3021, new_cis and new_cis6 are now covered by the promise
  • Each item names its replacement. :old_nth is left out, being a compatibility switch that has never been marked deprecated and has no replacement.
  • Warn in the deprecated category when :aton, new_cis or new_cis6 is used, naming the replacement in the warning (GH#49). None of the three warned before, though all were marked deprecated:
    • :aton warns on import in both IP.pm and Lite.pm
    • new_cis and new_cis6 warn on call; they are defined once in Lite.pm and reached from IP.pm via AUTOLOAD
  • Behaviour of all three is unchanged, except under use warnings FATAL => 'all', where the new warning dies; no warnings 'deprecated' silences it. For an import like :aton that silence has to come before the use, since the import runs at BEGIN time.
  • Require Math::BigInt 1.99, the last release before perl 5.14 (GH#44)
  • Remove duplicate NAME section from the Constants.pm POD
  • Adjust Constants.pm POD: name each constant with its sigil and indent descriptions consistently
  • Convert SEE ALSO sections to L<...> links and drop the (3) suffixes
  • Uniform code formatting across lib/, following UtilPP.pm:
    • 4 spaces per indent level, no tabs
    • space after commas, my (...) rather than my(...)
    • =item rather than =item *
    • else and elsif on their own line, not cuddled to the brace
  • POD is unchanged by the reindent; verbatim examples keep their two-space first level.
  • Fix {1,3} regex quantifiers broken by a stray space, which had disabled the mixed hex/dot-quad branch of InetBase::ipv6_aton and the masklen check in coalesce
  • Write the shipped Makefile.PL source as inc/MakeMaker/header.pl and reapply the style pass there, so the tarball no longer ships the old use vars, indent and =item * forms (GH#85)
  • Drop AutoLoader from the prerequisites; nothing loads it since GH#70
  • Drop vars from the prerequisites; generated Util_IS.pm now declares its version with our $VERSION
  • Remove the Math::BigInt emulation switch from Lite.pm (GH#84):
    • _force_bi_emu and $no_mbi_emu are gone, and _loadMBI always runs the require, so bigint() no longer croaks on a host that has Math::BigInt installed
    • drop the stale note on the three known Math::BigInt flavors
  • Document the numeric() comparison hazard in the Lite.pm POD: an ipV6 value has more digits than a Perl number holds, so ==, <=> and sort treat distinct addresses as equal (GH#84)

Changes for version 4.080_02 - 2026-09-29 (TRIAL RELEASE)

  • Fix re6() to support compressed IPv6 addresses (::) and shortened groups (GH#14)
  • Fix bcd2bin/bcdn2bin error messages to show correct function name (GH#78)
  • Add :all export tag to NetAddr::IP::Constants (GH#81)
  • Remove broken _bi_fake fallback in bigint(): Math::BigInt now required for bigint() support, added to RuntimeRecommends (GH#44)
  • Fix SYNOPSIS in IP.pm and Lite.pm (GH#74 items 3-9):
    • Fix within() example, consolidate my $ip declarations
    • Fix prose indentation, typo "Domanin" -> "Domain"
    • Fix unbalanced parenthesis, fix Zeros/Ones/V4mask/V4net description
  • Fix comment in Lite.pm: 0xfffffffe is 2**32 - 2, not 2**32 - 1 (GH#79)
  • Fix module load without resolver: replace inet_aton('255.0.0.0') with pack() (GH#69)
  • Fix Storable hooks: install at file scope, :old_storable is sticky (GH#8)
  • Re-enable tail-call goto dispatches removed in commit 9743c94:
    • IP.pm: splitref/rsplitref -> goto &_splitref
    • UtilPP.pm: addconst/add128/sub128 -> goto &slowadd128
    • UtilPP.pm: bcd2bin -> &_bcdcheck; goto &_bcd2bin
    • UtilPP.pm: bin2bcdn -> goto &_bin2bcdn
    • UtilPP.pm: comp128 restored to return ~ $_[0]
  • Convert @ISA + require Exporter to use parent in all modules
  • Replace use vars with our declarations, consolidate declaration + init
  • Convert tabs to spaces and fix POD indentation in IP.pm and Lite.pm

Changes for version 4.080_01 - 2026-09-22 (TRIAL RELEASE)

  • Validate masklen and number in coalesce, croak on bad arguments (GH#40)
  • Fix coalesce on subclass objects (GH#38)
  • Fix coalesce to count subnet addresses, not usable hosts (GH#37)
  • new6() returns compatible form for IPv4-only hosts, not mapped form (GH#64)
  • Add neg and abs overloads with clear error messages (GH#67)
  • Anchor bracket notation match to reject text outside brackets (GH#68)
  • Fix licence metadata and restore Artistic text (GH#56)
  • new6FFFF returns undef on invalid input instead of unblessed hash ref (GH#65)
  • BREAKING: re() on IPv6 objects in IPv4 space no longer emits a broken regex (GH#34)
  • BREAKING: re6() now returns a non-capturing group (?:...) (GH#50)
  • new6() now prefers AAAA over A for dual-stack hostnames, RT#119858 (GH#32)
  • Deprecate :rfc3021 tag; hostenum/hostenumref return 2 hosts for /31 and /127 unconditionally (GH#26)
  • BREAKING: new(undef) returns undef instead of the default route (GH#29)
  • Fix is_local for IPv4 loopback held in IPv6 objects (GH#27)
  • Fix pure-Perl _bcdcheck error messages (GH#23)
  • Remove dead branch in _splitplan, use named loop variable (GH#18)
  • Add BCD boundary input test suite (GH#51)
  • Preserve caller $@ and $SIG{__DIE__} on oversized decimal in new() (GH#59)
  • Localize $SIG{__DIE__} in module load eval probes, RT#130949 (GH#30)
  • Fix POD spelling mistakes: complier, alway, netowrk, occurence, RT#114239 (GH#47)
  • Prevent re() from matching addresses embedded in longer dotted strings (GH#35)
  • Reject cross-family and non-object arguments in within() and contains() (GH#28)
  • Remove faulty _splitplan pre-check that rejected valid short plans (GH#58)
  • Fix Compact merging v4 with v6 and mutating arguments (GH#15)
  • Fix compactref on subclasses (GH#16)
  • Reject bracket-enclosed IPv4 literals (GH#60)
  • Assert mode() matches Makefile.PL build choice (GH#61)
  • Reject empty string mask in constructor (GH#3)
  • Croak on swapped subtraction constant - object (GH#24)
  • Fix plus() alias for zero and silent no-op outside 32-bit range (GH#25)
  • Detect overflow in decimal integers, return undef in constructor (GH#19)
  • Support [addr]/mask URI bracket notation (GH#2)
  • Fix _splitplan netlimit pre-check and croak (GH#17)
  • Reject non-integer indices in nth() (GH#10)
  • Fix 0b/0x literal parsing using oct() instead of string eval (GH#4)
  • Reject non-ASCII digits in IP parsing
  • Fix version() for large decimal integers, RT#117995 (GH#31)
  • Document coalesce() behavior for equal-length masks (GH#45)
  • Fix bcdn2bin length check to report digits not bytes (GH#53)
  • Make Socket6 an optional recommends, not hard prereq (GH#54)
  • Modernize POD: indirect object syntax and RFC 5737 doc addresses
  • Bump perl requirement to 5.014 and fix Test2 imports (GH#57)
  • Remove Perl 5.10 and 5.12 from CI matrix (GH#57)
  • Consolidate sub-distributions into conventional Dist::Zilla layout
  • Convert all test files to Test2::V1
  • Fix :nofqdn import tag to actually set the flag, RT#111301 (GH#1)

Modules

Manages IPv4 and IPv6 addresses and subnets
Magic number constants for NetAddr::IP
IPv4 and IPv6 address parsing and formatting utilities
Manages IPv4 and IPv6 addresses and subnets (lightweight)
Native C and pure perl implementations of IPv4 and IPv6 address utilities
Pure perl implementations of IPv4 and IPv6 address utilities

Provides

in lib/NetAddr/IP/Util.pm