Fix potential crash in QNetworkInformation if no network is available

In some circumstances, an empty QDBusInterface was created. However,
this can lead to a crash on some systems (observed in Ubuntu 20.04).
The crash happens, when no network is available.

Pick-to: 6.3
Change-Id: I37316db547f33f082b8aaa73494db1bdf5aded1d
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Simeon Kuran 2022-04-25 13:37:53 +02:00
parent 464418f5de
commit 64af542374

View File

@ -119,20 +119,21 @@ QNetworkManagerInterface::NMConnectivityState QNetworkManagerInterface::connecti
return QNetworkManagerInterface::NM_CONNECTIVITY_UNKNOWN; return QNetworkManagerInterface::NM_CONNECTIVITY_UNKNOWN;
} }
static QDBusInterface getPrimaryDevice(const QDBusObjectPath &devicePath) static std::optional<QDBusInterface> getPrimaryDevice(const QDBusObjectPath &devicePath)
{ {
const QDBusInterface connection(NM_DBUS_SERVICE, devicePath.path(), const QDBusInterface connection(NM_DBUS_SERVICE, devicePath.path(),
NM_CONNECTION_DBUS_INTERFACE, QDBusConnection::systemBus()); NM_CONNECTION_DBUS_INTERFACE, QDBusConnection::systemBus());
if (!connection.isValid()) if (!connection.isValid())
return QDBusInterface({}, {}); return std::nullopt;
const auto devicePaths = connection.property("Devices").value<QList<QDBusObjectPath>>(); const auto devicePaths = connection.property("Devices").value<QList<QDBusObjectPath>>();
if (devicePaths.isEmpty()) if (devicePaths.isEmpty())
return QDBusInterface({}, {}); return std::nullopt;
const QDBusObjectPath primaryDevicePath = devicePaths.front(); const QDBusObjectPath primaryDevicePath = devicePaths.front();
return QDBusInterface(NM_DBUS_SERVICE, primaryDevicePath.path(), NM_DEVICE_DBUS_INTERFACE, return std::make_optional<QDBusInterface>(NM_DBUS_SERVICE, primaryDevicePath.path(),
QDBusConnection::systemBus()); NM_DEVICE_DBUS_INTERFACE,
QDBusConnection::systemBus());
} }
std::optional<QDBusObjectPath> QNetworkManagerInterface::primaryConnectionDevicePath() const std::optional<QDBusObjectPath> QNetworkManagerInterface::primaryConnectionDevicePath() const
@ -160,10 +161,12 @@ auto QNetworkManagerInterface::meteredState() const -> NMMetered
auto QNetworkManagerInterface::extractDeviceType(const QDBusObjectPath &devicePath) const auto QNetworkManagerInterface::extractDeviceType(const QDBusObjectPath &devicePath) const
-> NMDeviceType -> NMDeviceType
{ {
QDBusInterface primaryDevice = getPrimaryDevice(devicePath); const auto primaryDevice = getPrimaryDevice(devicePath);
if (!primaryDevice.isValid()) if (!primaryDevice)
return NM_DEVICE_TYPE_UNKNOWN; return NM_DEVICE_TYPE_UNKNOWN;
const QVariant deviceType = primaryDevice.property("DeviceType"); if (!primaryDevice->isValid())
return NM_DEVICE_TYPE_UNKNOWN;
const QVariant deviceType = primaryDevice->property("DeviceType");
if (!deviceType.isValid()) if (!deviceType.isValid())
return NM_DEVICE_TYPE_UNKNOWN; return NM_DEVICE_TYPE_UNKNOWN;
return static_cast<NMDeviceType>(deviceType.toUInt()); return static_cast<NMDeviceType>(deviceType.toUInt());
@ -172,10 +175,12 @@ auto QNetworkManagerInterface::extractDeviceType(const QDBusObjectPath &devicePa
auto QNetworkManagerInterface::extractDeviceMetered(const QDBusObjectPath &devicePath) const auto QNetworkManagerInterface::extractDeviceMetered(const QDBusObjectPath &devicePath) const
-> NMMetered -> NMMetered
{ {
QDBusInterface primaryDevice = getPrimaryDevice(devicePath); const auto primaryDevice = getPrimaryDevice(devicePath);
if (!primaryDevice.isValid()) if (!primaryDevice)
return NM_METERED_UNKNOWN; return NM_METERED_UNKNOWN;
const QVariant metered = primaryDevice.property("Metered"); if (!primaryDevice->isValid())
return NM_METERED_UNKNOWN;
const QVariant metered = primaryDevice->property("Metered");
if (!metered.isValid()) if (!metered.isValid())
return NM_METERED_UNKNOWN; return NM_METERED_UNKNOWN;
return static_cast<NMMetered>(metered.toUInt()); return static_cast<NMMetered>(metered.toUInt());