config(legacy): null-check getConfigValueSafeDevice in getDevice* getters

getConfigValueSafeDevice can return nullptr when:
- the device has no matching special config entry, and
- the fallback string is empty (default for getDevice* caller)

This caused a null dereference in getDeviceInt, getDeviceFloat,
getDeviceVec, and getDeviceString when called for devices without
a explicit config block. InputManager.cpp:1170 (keyboard tags)
and :1301 (mouse tags) hit this on startup for any device that
doesn't has a device { name = ...; tags = ...; } entry.

The tags feature was added in r320, exposing this latent bugs.

Fix by storing the pointer local and returning type-appropriate
defaults (0, 0.F, {0,0}, "") when nullptr.

Fixes: 497b48e ("config: add device tags (#13728)")
This commit is contained in:
Ronny Dudeck 2026-05-06 08:20:08 +02:00
parent a531c2ed6b
commit eefb254de1

View file

@ -1134,25 +1134,34 @@ bool CConfigManager::deviceConfigExplicitlySet(const std::string& dev, const std
}
int CConfigManager::getDeviceInt(const std::string& dev, const std::string& v, const std::string& fallback) {
return std::any_cast<Hyprlang::INT>(getConfigValueSafeDevice(dev, v, fallback)->getValue());
const auto VAL = getConfigValueSafeDevice(dev, v, fallback);
return VAL ? std::any_cast<Hyprlang::INT>(VAL->getValue()) : 0;
}
float CConfigManager::getDeviceFloat(const std::string& dev, const std::string& v, const std::string& fallback) {
return std::any_cast<Hyprlang::FLOAT>(getConfigValueSafeDevice(dev, v, fallback)->getValue());
const auto VAL = getConfigValueSafeDevice(dev, v, fallback);
return VAL ? std::any_cast<Hyprlang::FLOAT>(VAL->getValue()) : 0.F;
}
Vector2D CConfigManager::getDeviceVec(const std::string& dev, const std::string& v, const std::string& fallback) {
auto vec = std::any_cast<Hyprlang::VEC2>(getConfigValueSafeDevice(dev, v, fallback)->getValue());
const auto VAL = getConfigValueSafeDevice(dev, v, fallback);
if (!VAL)
return {0, 0};
auto vec = std::any_cast<Hyprlang::VEC2>(VAL->getValue());
return {vec.x, vec.y};
}
std::string CConfigManager::getDeviceString(const std::string& dev, const std::string& v, const std::string& fallback) {
auto VAL = std::string{std::any_cast<Hyprlang::STRING>(getConfigValueSafeDevice(dev, v, fallback)->getValue())};
if (VAL == STRVAL_EMPTY)
const auto VAL = getConfigValueSafeDevice(dev, v, fallback);
if (!VAL)
return "";
return VAL;
auto STR = std::string{std::any_cast<Hyprlang::STRING>(VAL->getValue())};
if (STR == STRVAL_EMPTY)
return "";
return STR;
}
SConfigOptionReply CConfigManager::getConfigValue(const std::string& val) {