DHCP IPv4 range subnet validation returns early because it reads gateway fields at the wrong nesting level
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
validateIpForGatewaySubnetMask checks allValues.gateway_ip and allValues.subnet_mask, but the form stores these values under allValues.v4. For the real form value shape, the validator returns undefined before checking subnet membership.
Steps to reproduce
- Set gateway
192.168.1.1and mask255.255.255.0in DHCP IPv4 settings. - Enter a range outside that subnet, such as
10.0.0.100–10.0.0.200. - Validate the range fields.
To isolate this from unrelated IPv6 form validation, use an interface without IPv6 addresses or an otherwise valid IPv6 section.
Expected result
The range fields show the existing subnet_error validation message before submission.
Actual result
The subnet validator accepts these fields. The backend does validate subnet membership, so this is a missing frontend validation, not a claim that the DHCP server accepts or leases addresses from the wrong subnet. Saving invalid values reaches the server-side rejection instead of the intended field error.
Minimal reproduction
Calling the original exported validator:
validateIpForGatewaySubnetMask('10.0.0.100', {
v4: {
gateway_ip: '192.168.1.1',
subnet_mask: '255.255.255.0',
range_start: '10.0.0.100',
range_end: '10.0.0.200',
lease_duration: 86400,
},
});
// Actual: undefined (accepted)
// Expected: a translated subnet_error messageThis was reproduced using the original validator, with translation calls returning their message keys.
Cause / possible fix
The early guard in validators.ts reads root-level fields, while the destructuring immediately below correctly reads allValues.v4.
Check allValues.v4.gateway_ip and allValues.v4.subnet_mask in the guard, and cover an out-of-subnet range using the real nested form shape. Both range inputs use this validator in FormDHCPv4.tsx.
Backend rejection is implemented in V4ServerConf.Validate.
Source: AdguardTeam/AdGuardHome