From ca9542adec87110556601d7ce48381ea8d13e692 Mon Sep 17 00:00:00 2001
From: Stig Palmquist <git@stig.io>
Date: Sun, 10 May 2026 19:37:26 +0200
Subject: [PATCH] CVE-2026-45190: Reject Unicode digits and trailing newlines
 in parsers

The parser regexes used \d (matches the Unicode Nd category) and
/^...$/ (matches before a trailing "\n"). Both let inputs slip past
the validators that pack("H*",...) and numeric coercion then
re-encoded to a different address. Possibly allowing IP ACL bypass
via find().

Assisted-by: Claude (Anthropic)
Signed-off-by: Stig Palmquist <git@stig.io>
---
 Lite.pm | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/Lite.pm b/Lite.pm
index 005ebbe..8b5a20c 100644
--- a/Lite.pm
+++ b/Lite.pm
@@ -37,7 +37,7 @@ sub add {
     my ($ip, $mask) = split "/", shift;
     $self->_init($ip) || confess "Can't determine ip format" unless %$self;
     confess "Bad mask $mask"
-        unless $mask =~ /^\d+$/ and $mask <= $self->{NBITS}-8;
+        unless $mask =~ /\A[0-9]+\z/ and $mask <= $self->{NBITS}-8;
     $mask += 8;
     my $start = $self->{PACK}->($ip) & $self->{MASKS}[$mask]
         or confess "Bad ip address: $ip";
@@ -181,7 +181,7 @@ sub _pack_ipv4 {
     my @nums = split /\./, shift(), -1;
     return unless @nums == 4;
     for (@nums) {
-        return unless /^\d{1,3}$/ and !/^0\d{1,2}$/ and $_ <= 255;
+        return unless /\A[0-9]{1,3}\z/ and !/\A0[0-9]{1,2}\z/ and $_ <= 255;
     }
     pack("CC*", 0, @nums);
 }
@@ -192,15 +192,15 @@ sub _unpack_ipv4 {
 
 sub _pack_ipv6 {
     my $ip = shift;
-    $ip =~ s/^::$/::0/;
-    return if $ip =~ /^:/ and $ip !~ s/^::/:/;
-    return if $ip =~ /:$/ and $ip !~ s/::$/:/;
+    $ip =~ s/\A::\z/::0/;
+    return if $ip =~ /\A:/ and $ip !~ s/\A::/:/;
+    return if $ip =~ /:\z/ and $ip !~ s/::\z/:/;
     my @nums = split /:/, $ip, -1;
     return unless @nums <= 8;
     my ($empty, $ipv4, $str) = (0,'','');
     for (@nums) {
         return if $ipv4;
-        $str .= "0" x (4-length) . $_, next if /^[a-fA-F\d]{1,4}$/;
+        $str .= "0" x (4-length) . $_, next if /\A[a-fA-F0-9]{1,4}\z/;
         do { return if $empty++ }, $str .= "X", next if $_ eq '';
         next if $ipv4 = _pack_ipv4($_);
         return;

