Client ID validation rejects valid IPv6 CIDRs with an embedded dotted-decimal IPv4 address
Version and test environment
master at aad2e15ffc403993f60c9c9cba2ef8dd85e18479. Source checkout; isolated frontend reproduction with Node.js 18.19.1. These results come from the actual source components/validators, not an end-to-end test against a running AdGuard Home installation. No production DHCP configuration was changed.
Summary
The persistent-client identifier validator rejects a valid IPv6 CIDR in mixed IPv6/IPv4 notation, but accepts the equivalent hexadecimal notation.
Steps to reproduce
- Open Settings → Client settings and add or edit a persistent client.
- Enter
::ffff:192.168.1.0/120as an identifier. - Validate the field.
- Replace it with the equivalent
::ffff:c0a8:100/120and validate again.
Expected result
Both syntactically valid representations pass identifier validation.
Actual result and minimal reproduction
Calling the original validateClientId function, with translation calls returning their message keys:
validateClientId('::ffff:192.168.1.0/120');
// 'form_error_client_id_format'
validateClientId('::ffff:c0a8:100/120');
// undefined (accepted)
validateClientId('2001:db8::/64');
// undefined (accepted)The frontend dependency ipaddr.js 1.9.1 successfully parses all three strings with parseCIDR.
Cause / possible fix
R_CIDR_IPV6 in constants.ts contains literal d characters in embedded IPv4 octet patterns, such as 2[0-4]d, 1dd, and [1-9]?d, rather than digit escapes. It also uses unescaped dots in those branches.
validateClientId relies on this regex. The backend identifier parser uses netip.ParsePrefix in Persistent.setID.
Correct the regex or use the existing address parser for CIDR validation, with regression coverage for mixed notation and invalid octets. This report concerns syntax validation; it does not claim to test runtime matching of IPv4-mapped client addresses.
Source: AdguardTeam/AdGuardHome