From 8b5f34ff6986d810ec55fa54f72da3951c36d1df Mon Sep 17 00:00:00 2001 From: Volodymyr Date: Mon, 28 Sep 2026 14:32:10 +0300 Subject: [PATCH 1/3] fix(network_info_plus): Return null for Linux subnet mask and broadcast when IPv4 data is missing `_getSubnetMask` cast a missing prefix to `int`, throwing a TypeError when there was no primary connection, no ip4Config or empty addressData. `_getBroadcast` now also returns null instead of computing a bogus value from zero fallbacks. Co-Authored-By: Claude Opus 5.5 --- .../lib/src/network_info_plus_linux.dart | 8 +-- .../test/network_info_plus_linux_test.dart | 50 +++++++++++++++++-- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/packages/network_info_plus/network_info_plus/lib/src/network_info_plus_linux.dart b/packages/network_info_plus/network_info_plus/lib/src/network_info_plus_linux.dart index 92f2314729..a035d2f108 100644 --- a/packages/network_info_plus/network_info_plus/lib/src/network_info_plus_linux.dart +++ b/packages/network_info_plus/network_info_plus/lib/src/network_info_plus_linux.dart @@ -96,14 +96,16 @@ class NetworkInfoPlusLinuxPlugin extends NetworkInfoPlatform { } String? _getSubnetMask(List>? data) { - final prefix = data?.firstOrNull?['prefix'] as int; + final prefix = data?.firstOrNull?['prefix'] as int?; + if (prefix == null) return null; final mask = 0xffffffff >> (32 - prefix); return mask.toIpString(); } String? _getBroadcast(List>? data) { - final ip = _getIpAddress(data)?.toIpInt() ?? 0; - final mask = _getSubnetMask(data)?.toIpInt() ?? 0; + final ip = _getIpAddress(data)?.toIpInt(); + final mask = _getSubnetMask(data)?.toIpInt(); + if (ip == null || mask == null) return null; return (ip | (mask ^ 0xffffffff)).toIpString(); } diff --git a/packages/network_info_plus/network_info_plus/test/network_info_plus_linux_test.dart b/packages/network_info_plus/network_info_plus/test/network_info_plus_linux_test.dart index dc5ab1195a..c1908e8fe4 100644 --- a/packages/network_info_plus/network_info_plus/test/network_info_plus_linux_test.dart +++ b/packages/network_info_plus/network_info_plus/test/network_info_plus_linux_test.dart @@ -1,13 +1,57 @@ -@TestOn('linux') -library; - import 'package:flutter_test/flutter_test.dart'; import 'package:network_info_plus/network_info_plus.dart'; import 'package:network_info_plus_platform_interface/network_info_plus_platform_interface.dart'; +import 'package:nm/nm.dart'; void main() { test('registered instance', () { NetworkInfoPlusLinuxPlugin.registerWith(); expect(NetworkInfoPlatform.instance, isA()); }); + + group('missing IPv4 data returns null', () { + final cases = { + 'primaryConnection is null': () => null, + 'ip4Config is null': () => _FakeConnection(null), + 'addressData is empty': () => _FakeConnection(_FakeIp4Config([])), + }; + + for (final MapEntry(key: description, value: connection) in cases.entries) { + test(description, () async { + final plugin = NetworkInfoPlusLinuxPlugin() + ..createClient = () => _FakeClient(connection()); + + expect(await plugin.getWifiSubmask(), isNull); + expect(await plugin.getWifiBroadcast(), isNull); + expect(await plugin.getWifiIP(), isNull); + }); + } + }); +} + +class _FakeClient extends Fake implements NetworkManagerClient { + _FakeClient(this.primaryConnection); + + @override + final NetworkManagerActiveConnection? primaryConnection; + + @override + Future connect() async {} + + @override + Future close() async {} +} + +class _FakeConnection extends Fake implements NetworkManagerActiveConnection { + _FakeConnection(this.ip4Config); + + @override + final NetworkManagerIP4Config? ip4Config; +} + +class _FakeIp4Config extends Fake implements NetworkManagerIP4Config { + _FakeIp4Config(this.addressData); + + @override + final List> addressData; } From 951d02727fa7c7ae9424e06c14d0a4a2f87e84c0 Mon Sep 17 00:00:00 2001 From: Volodymyr Date: Mon, 28 Sep 2026 14:32:10 +0300 Subject: [PATCH 2/3] fix(network_info_plus): Return null for Linux subnet mask and broadcast when IPv4 data is missing `_getSubnetMask` cast a missing prefix to `int`, throwing a TypeError when there was no primary connection, no ip4Config or empty addressData. `_getBroadcast` now also returns null instead of computing a bogus value from zero fallbacks. Co-Authored-By: Claude Opus 5.5 --- .../lib/src/network_info_plus_linux.dart | 8 +-- .../test/network_info_plus_linux_test.dart | 50 +++++++++++++++++-- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/packages/network_info_plus/network_info_plus/lib/src/network_info_plus_linux.dart b/packages/network_info_plus/network_info_plus/lib/src/network_info_plus_linux.dart index 92f2314729..a035d2f108 100644 --- a/packages/network_info_plus/network_info_plus/lib/src/network_info_plus_linux.dart +++ b/packages/network_info_plus/network_info_plus/lib/src/network_info_plus_linux.dart @@ -96,14 +96,16 @@ class NetworkInfoPlusLinuxPlugin extends NetworkInfoPlatform { } String? _getSubnetMask(List>? data) { - final prefix = data?.firstOrNull?['prefix'] as int; + final prefix = data?.firstOrNull?['prefix'] as int?; + if (prefix == null) return null; final mask = 0xffffffff >> (32 - prefix); return mask.toIpString(); } String? _getBroadcast(List>? data) { - final ip = _getIpAddress(data)?.toIpInt() ?? 0; - final mask = _getSubnetMask(data)?.toIpInt() ?? 0; + final ip = _getIpAddress(data)?.toIpInt(); + final mask = _getSubnetMask(data)?.toIpInt(); + if (ip == null || mask == null) return null; return (ip | (mask ^ 0xffffffff)).toIpString(); } diff --git a/packages/network_info_plus/network_info_plus/test/network_info_plus_linux_test.dart b/packages/network_info_plus/network_info_plus/test/network_info_plus_linux_test.dart index dc5ab1195a..c1908e8fe4 100644 --- a/packages/network_info_plus/network_info_plus/test/network_info_plus_linux_test.dart +++ b/packages/network_info_plus/network_info_plus/test/network_info_plus_linux_test.dart @@ -1,13 +1,57 @@ -@TestOn('linux') -library; - import 'package:flutter_test/flutter_test.dart'; import 'package:network_info_plus/network_info_plus.dart'; import 'package:network_info_plus_platform_interface/network_info_plus_platform_interface.dart'; +import 'package:nm/nm.dart'; void main() { test('registered instance', () { NetworkInfoPlusLinuxPlugin.registerWith(); expect(NetworkInfoPlatform.instance, isA()); }); + + group('missing IPv4 data returns null', () { + final cases = { + 'primaryConnection is null': () => null, + 'ip4Config is null': () => _FakeConnection(null), + 'addressData is empty': () => _FakeConnection(_FakeIp4Config([])), + }; + + for (final MapEntry(key: description, value: connection) in cases.entries) { + test(description, () async { + final plugin = NetworkInfoPlusLinuxPlugin() + ..createClient = () => _FakeClient(connection()); + + expect(await plugin.getWifiSubmask(), isNull); + expect(await plugin.getWifiBroadcast(), isNull); + expect(await plugin.getWifiIP(), isNull); + }); + } + }); +} + +class _FakeClient extends Fake implements NetworkManagerClient { + _FakeClient(this.primaryConnection); + + @override + final NetworkManagerActiveConnection? primaryConnection; + + @override + Future connect() async {} + + @override + Future close() async {} +} + +class _FakeConnection extends Fake implements NetworkManagerActiveConnection { + _FakeConnection(this.ip4Config); + + @override + final NetworkManagerIP4Config? ip4Config; +} + +class _FakeIp4Config extends Fake implements NetworkManagerIP4Config { + _FakeIp4Config(this.addressData); + + @override + final List> addressData; } From 25636102f82eddecce03d2024bb565cb557e6e89 Mon Sep 17 00:00:00 2001 From: Volodymyr Date: Tue, 29 Sep 2026 13:38:09 +0300 Subject: [PATCH 3/3] ci(network_info_plus): silence experimental coroutine deprecation error on Windows example Newer MSVC in the windows-latest image turns STL1011 into a hard error, which breaks permission_handler_windows. Co-Authored-By: Claude Sonnet 5.5 --- .../network_info_plus/example/windows/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/network_info_plus/network_info_plus/example/windows/CMakeLists.txt b/packages/network_info_plus/network_info_plus/example/windows/CMakeLists.txt index abf90408ef..790ed4d475 100644 --- a/packages/network_info_plus/network_info_plus/example/windows/CMakeLists.txt +++ b/packages/network_info_plus/network_info_plus/example/windows/CMakeLists.txt @@ -29,6 +29,11 @@ set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") # Use Unicode for all projects. add_definitions(-DUNICODE -D_UNICODE) +# Newer MSVC (VS 2026) turns the deprecation of into a +# hard error. permission_handler_windows still uses it, so silence it for all +# targets (including plugins) until that package is updated. +add_definitions(-D_SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS) + # Compilation settings that should be applied to most targets. function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_17)